diff options
author | Jo Shields <directhex@apebox.org> | 2014-02-19 22:12:43 +0000 |
---|---|---|
committer | Jo Shields <directhex@apebox.org> | 2014-02-19 22:12:43 +0000 |
commit | 9972bf87b4f27d9c8f358ef8414ac1ab957a2f0f (patch) | |
tree | 5bb230c1d698659115f918e243c1d4b0aa4c7f51 /external/ikvm/openjdk | |
parent | d0a215f5626219ff7927f576588a777e5331c7be (diff) | |
download | mono-upstream/3.2.8+dfsg.tar.gz |
Imported Upstream version 3.2.8+dfsgupstream/3.2.8+dfsg
Diffstat (limited to 'external/ikvm/openjdk')
62 files changed, 3124 insertions, 5176 deletions
diff --git a/external/ikvm/openjdk/FORKED b/external/ikvm/openjdk/FORKED new file mode 100644 index 0000000000..64e8faf23a --- /dev/null +++ b/external/ikvm/openjdk/FORKED @@ -0,0 +1,132 @@ +# +# IKVM.NET Forked OpenJDK Files +# +# This file list all forked OpenJDK files in their original OpenJDK location and their forked ikvm/openjdk location. +# Each line not starting with # contains a mapping: <original>=<forked> +# +build/linux-amd64/gensrc/sun/misc/Version.java=sun/misc/Version.java +build/linux-amd64/gensrc/sun/nio/ch/SocketOptionRegistry.java=sun/nio/ch/SocketOptionRegistry.java +build/linux-amd64/gensrc/sun/nio/cs/StandardCharsets.java=sun/nio/cs/StandardCharsets.java +jdk/src/macosx/classes/java/lang/ClassLoaderHelper.java=java/lang/ClassLoaderHelper.java +jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java=com/sun/imageio/plugins/jpeg/JPEGImageReader.java +jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java=com/sun/imageio/plugins/jpeg/JPEGImageWriter.java +jdk/src/share/classes/java/awt/Font.java=java/awt/Font.java +jdk/src/share/classes/java/awt/GraphicsConfiguration.java=java/awt/GraphicsConfiguration.java +jdk/src/share/classes/java/awt/Image.java=java/awt/Image.java +jdk/src/share/classes/java/awt/image/BufferedImage.java=java/awt/image/BufferedImage.java +jdk/src/share/classes/java/awt/image/DataBuffer.java=java/awt/image/DataBuffer.java +jdk/src/share/classes/java/awt/image/DataBufferByte.java=java/awt/image/DataBufferByte.java +jdk/src/share/classes/java/awt/image/DataBufferDouble.java=java/awt/image/DataBufferDouble.java +jdk/src/share/classes/java/awt/image/DataBufferFloat.java=java/awt/image/DataBufferFloat.java +jdk/src/share/classes/java/awt/image/DataBufferInt.java=java/awt/image/DataBufferInt.java +jdk/src/share/classes/java/awt/image/DataBufferShort.java=java/awt/image/DataBufferShort.java +jdk/src/share/classes/java/awt/image/DataBufferUShort.java=java/awt/image/DataBufferUShort.java +jdk/src/share/classes/java/awt/image/IndexColorModel.java=java/awt/image/IndexColorModel.java +jdk/src/share/classes/java/io/FileInputStream.java=java/io/FileInputStream.java +jdk/src/share/classes/java/io/FileOutputStream.java=java/io/FileOutputStream.java +jdk/src/share/classes/java/io/ObjectStreamClass.java=java/io/ObjectStreamClass.java +jdk/src/share/classes/java/io/ObjectStreamField.java=java/io/ObjectStreamField.java +jdk/src/share/classes/java/io/RandomAccessFile.java=java/io/RandomAccessFile.java +jdk/src/share/classes/java/lang/Class.java=java/lang/Class.java +jdk/src/share/classes/java/lang/ClassLoader.java=java/lang/ClassLoader.java +jdk/src/share/classes/java/lang/Enum.java=java/lang/Enum.java +jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java=java/lang/invoke/AdapterMethodHandle.java +jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java=java/lang/invoke/BoundMethodHandle.java +jdk/src/share/classes/java/lang/invoke/CallSite.java=java/lang/invoke/CallSite.java +jdk/src/share/classes/java/lang/invoke/ConstantCallSite.java=java/lang/invoke/ConstantCallSite.java +jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java=java/lang/invoke/DirectMethodHandle.java +jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java=java/lang/invoke/MethodHandleImpl.java +jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java=java/lang/invoke/MethodHandleNatives.java +jdk/src/share/classes/java/lang/invoke/MethodHandles.java=java/lang/invoke/MethodHandles.java +jdk/src/share/classes/java/lang/invoke/MutableCallSite.java=java/lang/invoke/MutableCallSite.java +jdk/src/share/classes/java/lang/invoke/VolatileCallSite.java=java/lang/invoke/VolatileCallSite.java +jdk/src/share/classes/java/lang/management/PlatformComponent.java=java/lang/management/PlatformComponent.java +jdk/src/share/classes/java/lang/Package.java=java/lang/Package.java +jdk/src/share/classes/java/lang/ref/SoftReference.java=java/lang/ref/SoftReference.java +jdk/src/share/classes/java/lang/reflect/Constructor.java=java/lang/reflect/Constructor.java +jdk/src/share/classes/java/lang/reflect/Field.java=java/lang/reflect/Field.java +jdk/src/share/classes/java/lang/reflect/Method.java=java/lang/reflect/Method.java +jdk/src/share/classes/java/lang/reflect/Proxy.java=java/lang/reflect/Proxy.java +jdk/src/share/classes/java/lang/Shutdown.java=java/lang/Shutdown.java +jdk/src/share/classes/java/lang/String.java=java/lang/StringHelper.java +jdk/src/share/classes/java/lang/System.java=java/lang/System.java +jdk/src/share/classes/java/lang/Thread.java=java/lang/Thread.java +jdk/src/share/classes/java/lang/Throwable.java=java/lang/ThrowableHelper.java +jdk/src/share/classes/java/net/SocketInputStream.java=java/net/SocketInputStream.java +jdk/src/share/classes/java/net/SocketOutputStream.java=java/net/SocketOutputStream.java +jdk/src/share/classes/java/nio/Bits.java=java/nio/Bits.java +jdk/src/share/classes/java/security/AccessController.java=java/security/AccessController.java +jdk/src/share/classes/java/security/ProtectionDomain.java=java/security/ProtectionDomain.java +jdk/src/share/classes/java/sql/DriverManager.java=java/sql/DriverManager.java +jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java=../classpath/java/util/concurrent/atomic/AtomicBoolean.java +jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java=../classpath/java/util/concurrent/atomic/AtomicInteger.java +jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java=../classpath/java/util/concurrent/atomic/AtomicIntegerArray.java +jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java=../classpath/java/util/concurrent/atomic/AtomicLong.java +jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java=../classpath/java/util/concurrent/atomic/AtomicLongArray.java +jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java=../classpath/java/util/concurrent/atomic/AtomicReference.java +jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java=../classpath/java/util/concurrent/atomic/AtomicReferenceArray.java +jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java=java/util/concurrent/locks/AbstractQueuedSynchronizer.java +jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java=java/util/concurrent/locks/LockSupport.java +jdk/src/share/classes/java/util/ResourceBundle.java=java/util/ResourceBundle.java +jdk/src/share/classes/java/util/TimeZone.java=java/util/TimeZone.java +jdk/src/share/classes/sun/awt/AppContext.java=sun/awt/AppContext.java +jdk/src/share/classes/sun/awt/EmbeddedFrame.java=sun/awt/EmbeddedFrame.java +jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java=sun/awt/image/ByteInterleavedRaster.java +jdk/src/share/classes/sun/awt/image/ImagingLib.java=sun/awt/image/ImagingLib.java +jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java=sun/awt/image/IntegerInterleavedRaster.java +jdk/src/share/classes/sun/awt/image/SunWritableRaster.java=sun/awt/image/SunWritableRaster.java +jdk/src/share/classes/sun/awt/image/ToolkitImage.java=sun/awt/image/ToolkitImage.java +jdk/src/share/classes/sun/awt/SunToolkit.java=sun/awt/SunToolkit.java +jdk/src/share/classes/sun/font/FontManager.java=sun/font/FontManager.java +jdk/src/share/classes/sun/font/StrikeCache.java=sun/font/StrikeCache.java +jdk/src/share/classes/sun/management/GcInfoBuilder.java=sun/management/GcInfoBuilder.java +jdk/src/share/classes/sun/management/ManagementFactoryHelper.java=sun/management/ManagementFactoryHelper.java +jdk/src/share/classes/sun/management/VMManagementImpl.java=sun/management/VMManagementImpl.java +jdk/src/share/classes/sun/misc/IoTrace.java=sun/misc/IoTrace.java +jdk/src/share/classes/sun/misc/JavaAWTAccess.java=sun/misc/JavaAWTAccess.java +jdk/src/share/classes/sun/misc/SharedSecrets.java=sun/misc/SharedSecrets.java +jdk/src/share/classes/sun/misc/VM.java=sun/misc/VM.java +jdk/src/share/classes/sun/net/sdp/SdpSupport.java=sun/net/sdp/SdpSupport.java +jdk/src/share/classes/sun/net/www/protocol/file/FileURLConnection.java=sun/net/www/protocol/file/FileURLConnection.java +jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java=sun/nio/ch/DatagramChannelImpl.java +jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java=sun/nio/ch/FileChannelImpl.java +jdk/src/share/classes/sun/nio/ch/IOUtil.java=sun/nio/ch/IOUtil.java +jdk/src/share/classes/sun/nio/ch/NativeDispatcher.java=sun/nio/ch/NativeDispatcher.java +jdk/src/share/classes/sun/nio/ch/Net.java=sun/nio/ch/Net.java +jdk/src/share/classes/sun/nio/ch/Util.java=sun/nio/ch/Util.java +jdk/src/share/classes/sun/reflect/CallerSensitive.java=sun/reflect/CallerSensitive.java +jdk/src/share/classes/sun/reflect/MethodAccessor.java=sun/reflect/MethodAccessor.java +jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java=sun/reflect/misc/ReflectUtil.java +jdk/src/share/classes/sun/reflect/Reflection.java=sun/reflect/Reflection.java +jdk/src/share/classes/sun/reflect/ReflectionFactory.java=sun/reflect/ReflectionFactory.java +jdk/src/solaris/classes/sun/nio/fs/UnixUriUtils.java=sun/nio/fs/UnixUriUtils.java +jdk/src/windows/classes/java/io/FileDescriptor.java=java/io/FileDescriptor.java +jdk/src/windows/classes/java/lang/ProcessImpl.java=java/lang/ProcessImpl.java +jdk/src/windows/classes/java/net/DefaultDatagramSocketImplFactory.java=java/net/DefaultDatagramSocketImplFactory.java +jdk/src/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java=java/net/DualStackPlainDatagramSocketImpl.java +jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java=java/net/DualStackPlainSocketImpl.java +jdk/src/windows/classes/java/net/PlainSocketImpl.java=java/net/PlainSocketImpl.java +jdk/src/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java=java/net/TwoStacksPlainDatagramSocketImpl.java +jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java=java/net/TwoStacksPlainSocketImpl.java +jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java=sun/awt/shell/Win32ShellFolder2.java +jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java=sun/awt/shell/Win32ShellFolderManager2.java +jdk/src/windows/classes/sun/misc/FileURLMapper.java=sun/misc/FileURLMapper.java +jdk/src/windows/classes/sun/net/dns/ResolverConfigurationImpl.java=sun/net/dns/ResolverConfigurationImpl.java +jdk/src/windows/classes/sun/net/www/protocol/file/Handler.java=sun/net/www/protocol/file/Handler.java +jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java=sun/net/www/protocol/jar/JarFileFactory.java +jdk/src/windows/classes/sun/nio/ch/DefaultSelectorProvider.java=sun/nio/ch/DefaultSelectorProvider.java +jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java=sun/nio/ch/FileDispatcherImpl.java +jdk/src/windows/classes/sun/nio/ch/Iocp.java=sun/nio/ch/Iocp.java +jdk/src/windows/classes/sun/nio/ch/PollArrayWrapper.java=sun/nio/ch/PollArrayWrapper.java +jdk/src/windows/classes/sun/nio/ch/SocketDispatcher.java=sun/nio/ch/SocketDispatcher.java +jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java=sun/nio/ch/WindowsAsynchronousFileChannelImpl.java +jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java=sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java +jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java=sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java +jdk/src/windows/classes/sun/nio/fs/WindowsUriSupport.java=sun/nio/fs/WindowsUriSupport.java +jdk/src/windows/classes/sun/print/Win32PrintJob.java=sun/print/Win32PrintJob.java +jdk/src/windows/classes/sun/print/Win32PrintService.java=sun/print/Win32PrintService.java +jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c=java/net/DualStackPlainDatagramSocketImpl_c.java +jdk/src/windows/native/java/net/DualStackPlainSocketImpl.c=java/net/DualStackPlainSocketImpl_c.java +jdk/src/windows/native/java/net/net_util_md.c=java/net/net_util_md.java +jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c=java/net/TwoStacksPlainDatagramSocketImpl_c.java +jdk/src/windows/native/java/net/TwoStacksPlainSocketImpl.c=java/net/TwoStacksPlainSocketImpl_c.java diff --git a/external/ikvm/openjdk/allsources.lst b/external/ikvm/openjdk/allsources.lst index 5df16cb52d..533d7645e2 100644 --- a/external/ikvm/openjdk/allsources.lst +++ b/external/ikvm/openjdk/allsources.lst @@ -4,7 +4,6 @@ ../classpath/ikvm/internal/AssemblyClassLoader.java ../classpath/ikvm/internal/CallerID.java ../classpath/ikvm/internal/Formatter.java -../classpath/ikvm/internal/HasCallerID.java ../classpath/ikvm/internal/JMath.java ../classpath/ikvm/internal/MonoUtils.java ../classpath/ikvm/internal/Util.java @@ -32,9 +31,7 @@ ../classpath/sun/misc/Ref.java AssemblyInfo.java com/sun/imageio/plugins/jpeg/JPEGImageReader.java -com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java com/sun/imageio/plugins/jpeg/JPEGImageWriter.java -com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java com/sun/management/OperatingSystem.java gnu/java/awt/Buffers.java gnu/java/awt/color/CieXyzConverter.java @@ -67,6 +64,13 @@ java/awt/image/BandCombineOp.java java/awt/image/BufferedImage.java java/awt/image/ConvolveOp.java java/awt/image/ColorConvertOp.java +java/awt/image/DataBuffer.java +java/awt/image/DataBufferByte.java +java/awt/image/DataBufferDouble.java +java/awt/image/DataBufferFloat.java +java/awt/image/DataBufferInt.java +java/awt/image/DataBufferShort.java +java/awt/image/DataBufferUShort.java java/awt/image/IndexColorModel.java java/awt/image/LookupOp.java java/awt/image/RescaleOp.java @@ -94,6 +98,7 @@ java/lang/invoke/MutableCallSite.java java/lang/invoke/VolatileCallSite.java java/lang/LangHelper.java java/lang/management/PlatformComponent.java +java/lang/Package.java java/lang/ProcessImpl.java java/lang/PropertyConstants.java java/lang/ref/Reference.java @@ -148,19 +153,15 @@ java/util/zip/StreamManipulator.java java/util/zip/ZipEntry.java java/util/zip/ZipFile.java sun/awt/AppContext.java -sun/awt/AppContextDC.java sun/awt/EmbeddedFrame.java sun/awt/IkvmDataTransferer.java -sun/awt/image/ByteComponentRaster.java -sun/awt/image/BytePackedRaster.java +sun/awt/image/ByteInterleavedRaster.java sun/awt/image/GifImageDecoder.java sun/awt/image/IkvmImageDecoder.java sun/awt/image/ImageRepresentation.java sun/awt/image/ImagingLib.java -sun/awt/image/IntegerComponentRaster.java +sun/awt/image/IntegerInterleavedRaster.java sun/awt/image/JPEGImageDecoder.java -sun/awt/image/OffScreenImageSource.java -sun/awt/image/ShortComponentRaster.java sun/awt/image/SunWritableRaster.java sun/awt/image/ToolkitImage.java sun/awt/shell/Win32ShellFolder2.java @@ -203,6 +204,8 @@ sun/management/GcInfoBuilder.java sun/management/ManagementFactoryHelper.java sun/management/VMManagementImpl.java sun/misc/FileURLMapper.java +sun/misc/IoTrace.java +sun/misc/JavaAWTAccess.java sun/misc/MiscHelper.java sun/misc/OSEnvironment.java sun/misc/SharedSecrets.java @@ -246,9 +249,11 @@ sun/print/UnixPrintServiceLookup.java sun/print/Win32PrintJob.java sun/print/Win32PrintService.java sun/print/Win32PrintServiceLookup.java +sun/reflect/CallerSensitive.java sun/reflect/MethodAccessor.java sun/reflect/Reflection.java sun/reflect/ReflectionFactory.java +sun/reflect/misc/ReflectUtil.java sun/security/jgss/wrapper/NativeGSSFactory.java sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/build/linux-amd64/gensrc/com/sun/accessibility/internal/resources/accessibility.java @@ -7451,6 +7456,8 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFWritableImageMetadata.java @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFWritableStreamMetadata.java @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java +@OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java +@OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java @OPENJDK7@/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java @@ -8572,13 +8579,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/ComponentColorModel.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/ComponentSampleModel.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/CropImageFilter.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBuffer.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferByte.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferDouble.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferFloat.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferInt.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferShort.java -@OPENJDK7@/jdk/src/share/classes/java/awt/image/DataBufferUShort.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/DirectColorModel.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/FilteredImageSource.java @OPENJDK7@/jdk/src/share/classes/java/awt/image/ImageConsumer.java @@ -8972,7 +8972,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/java/lang/OutOfMemoryError.java @OPENJDK7@/jdk/src/share/classes/java/lang/Override.java @OPENJDK7@/jdk/src/share/classes/java/lang/package-info.java -@OPENJDK7@/jdk/src/share/classes/java/lang/Package.java @OPENJDK7@/jdk/src/share/classes/java/lang/Process.java @OPENJDK7@/jdk/src/share/classes/java/lang/ProcessBuilder.java @OPENJDK7@/jdk/src/share/classes/java/lang/Readable.java @@ -11395,7 +11394,8 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/BufferedImageGraphicsConfig.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ByteArrayImageSource.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java -@OPENJDK7@/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java +@OPENJDK7@/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java +@OPENJDK7@/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/FileImageSource.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageConsumerQueue.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageDecoder.java @@ -11404,10 +11404,13 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageFormatException.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ImageWatched.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/InputStreamImageSource.java -@OPENJDK7@/jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java +@OPENJDK7@/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java +@OPENJDK7@/jdk/src/share/classes/sun/awt/image/NativeLibLoader.java +@OPENJDK7@/jdk/src/share/classes/sun/awt/image/OffScreenImageSource.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/PixelConverter.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/PNGImageDecoder.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java +@OPENJDK7@/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/URLImageSource.java @OPENJDK7@/jdk/src/share/classes/sun/awt/image/VSyncedBSManager.java @@ -12389,7 +12392,6 @@ sun/security/jgss/wrapper/SunNativeProvider.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/ConstructorUtil.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/FieldUtil.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java -@OPENJDK7@/jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java @OPENJDK7@/jdk/src/share/classes/sun/reflect/SignatureIterator.java @OPENJDK7@/jdk/src/share/classes/sun/rmi/log/LogHandler.java @OPENJDK7@/jdk/src/share/classes/sun/rmi/log/LogInputStream.java diff --git a/external/ikvm/openjdk/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/external/ikvm/openjdk/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java deleted file mode 100644 index 3b6c2e7422..0000000000 --- a/external/ikvm/openjdk/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.imageio.plugins.jpeg; - -import java.util.Locale; -import javax.imageio.spi.ImageReaderSpi; -import javax.imageio.stream.ImageInputStream; -import javax.imageio.spi.IIORegistry; -import javax.imageio.spi.ServiceRegistry; -import java.io.IOException; -import javax.imageio.ImageReader; -import javax.imageio.IIOException; - -public class JPEGImageReaderSpi extends ImageReaderSpi { - - private static String [] writerSpiNames = - {"com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi"}; - - private boolean registered = false; - - public JPEGImageReaderSpi() { - super(JPEG.vendor, - JPEG.version, - JPEG.names, - JPEG.suffixes, - JPEG.MIMETypes, - "com.sun.imageio.plugins.jpeg.JPEGImageReader", - new Class[] { ImageInputStream.class }, - writerSpiNames, - true, - JPEG.nativeStreamMetadataFormatName, - JPEG.nativeStreamMetadataFormatClassName, - null, null, - true, - JPEG.nativeImageMetadataFormatName, - JPEG.nativeImageMetadataFormatClassName, - null, null - ); - } - - public void onRegistration(ServiceRegistry registry, - Class<?> category) { - if (registered) { - return; - } - /* - try { - java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jpeg")); - // Stuff it all into one lib for first pass - //java.security.AccessController.doPrivileged( - //new sun.security.action.LoadLibraryAction("imageioIJG")); - } catch (Throwable e) { // Fail on any Throwable - // if it can't be loaded, deregister and return - registry.deregisterServiceProvider(this); - return; - } - */ - - registered = true; - } - - public String getDescription(Locale locale) { - return "Standard JPEG Image Reader"; - } - - public boolean canDecodeInput(Object source) throws IOException { - if (!(source instanceof ImageInputStream)) { - return false; - } - ImageInputStream iis = (ImageInputStream) source; - iis.mark(); - // If the first two bytes are a JPEG SOI marker, it's probably - // a JPEG file. If they aren't, it definitely isn't a JPEG file. - int byte1 = iis.read(); - int byte2 = iis.read(); - iis.reset(); - if ((byte1 == 0xFF) && (byte2 == JPEG.SOI)) { - return true; - } - return false; - } - - public ImageReader createReaderInstance(Object extension) - throws IIOException { - return new JPEGImageReader(this); - } - -} diff --git a/external/ikvm/openjdk/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/external/ikvm/openjdk/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java deleted file mode 100644 index ef3a1ea151..0000000000 --- a/external/ikvm/openjdk/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.imageio.plugins.jpeg; - -import javax.imageio.spi.ImageWriterSpi; -import javax.imageio.spi.ServiceRegistry; -import javax.imageio.spi.IIORegistry; -import javax.imageio.stream.ImageOutputStream; -import javax.imageio.ImageWriter; -import javax.imageio.ImageTypeSpecifier; -import javax.imageio.IIOException; - -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.SampleModel; -import java.util.Locale; - -public class JPEGImageWriterSpi extends ImageWriterSpi { - - private static String [] readerSpiNames = - {"com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi"}; - - private boolean registered = false; - - public JPEGImageWriterSpi() { - super(JPEG.vendor, - JPEG.version, - JPEG.names, - JPEG.suffixes, - JPEG.MIMETypes, - "com.sun.imageio.plugins.jpeg.JPEGImageWriter", - new Class[] { ImageOutputStream.class }, - readerSpiNames, - true, - JPEG.nativeStreamMetadataFormatName, - JPEG.nativeStreamMetadataFormatClassName, - null, null, - true, - JPEG.nativeImageMetadataFormatName, - JPEG.nativeImageMetadataFormatClassName, - null, null - ); - } - - public String getDescription(Locale locale) { - return "Standard JPEG Image Writer (not implemented)"; - } - - public void onRegistration(ServiceRegistry registry, - Class<?> category) { - if (registered) { - return; - } - /* - try { - java.security.AccessController.doPrivileged( - new sun.security.action.LoadLibraryAction("jpeg")); - } catch (Throwable e) { // Fail on any Throwable - // if it can't be loaded, deregister and return - registry.deregisterServiceProvider(this); - return; - } - */ - - registered = true; - } - - public boolean isFormatLossless() { - return false; - } - - public boolean canEncodeImage(ImageTypeSpecifier type) { - SampleModel sampleModel = type.getSampleModel(); - - // Find the maximum bit depth across all channels - int[] sampleSize = sampleModel.getSampleSize(); - int bitDepth = sampleSize[0]; - for (int i = 1; i < sampleSize.length; i++) { - if (sampleSize[i] > bitDepth) { - bitDepth = sampleSize[i]; - } - } - - // 4450894: Ensure bitDepth is between 1 and 8 - if (bitDepth < 1 || bitDepth > 8) { - return false; - } - - return true; - } - - public ImageWriter createWriterInstance(Object extension) - throws IIOException { - return new JPEGImageWriter(this); - } -} diff --git a/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java b/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java index 7ccf9f21bb..f2359e5498 100644 --- a/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java +++ b/external/ikvm/openjdk/ikvm/internal/AnnotationAttributeBase.java @@ -1,5 +1,5 @@ /* - Copyright (C) 2005-2011 Jeroen Frijters + Copyright (C) 2005-2013 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,11 +23,11 @@ */ package ikvm.internal; -import cli.System.Reflection.BindingFlags; import ikvm.lang.CIL; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Array; +import java.lang.reflect.GenericSignatureFormatError; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -36,13 +36,15 @@ import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.HashMap; +import sun.reflect.annotation.TypeNotPresentExceptionProxy; public abstract class AnnotationAttributeBase extends cli.System.Attribute implements Annotation, Serializable { - private final HashMap values = new HashMap(); private final Class annotationType; + private HashMap<String, Object> values; + private Object[] definition; private boolean frozen; protected AnnotationAttributeBase(Class annotationType) @@ -106,7 +108,7 @@ public abstract class AnnotationAttributeBase protected final synchronized void setValue(String name, Object value) { - if(frozen) + if(frozen || definition != null) { throw new IllegalStateException("Annotation properties have already been defined"); } @@ -115,7 +117,7 @@ public abstract class AnnotationAttributeBase Class type = annotationType.getMethod(name).getReturnType(); if(type.isEnum()) { - value = type.getMethod("valueOf", String.class).invoke(null, value.toString()); + value = Enum.valueOf(type, value.toString()); } else if(type == Class.class) { @@ -162,12 +164,11 @@ public abstract class AnnotationAttributeBase type = type.getComponentType(); if(type.isEnum()) { - Method valueOf = type.getMethod("valueOf", String.class); cli.System.Array orgarray = (cli.System.Array)value; Object[] array = (Object[])Array.newInstance(type, orgarray.get_Length()); for(int i = 0; i < array.length; i++) { - array[i] = valueOf.invoke(null, orgarray.GetValue(i).toString()); + array[i] = Enum.valueOf(type, orgarray.GetValue(i).toString()); } value = array; } @@ -190,47 +191,54 @@ public abstract class AnnotationAttributeBase { throw new InternalError("Invalid annotation type: " + type); } + if(values == null) + { + values = new HashMap<String, Object>(); + } values.put(name, value); } catch (NoSuchMethodException x) { throw (NoSuchMethodError)new NoSuchMethodError().initCause(x); } - catch (IllegalAccessException x) - { - throw (IllegalAccessError)new IllegalAccessError().initCause(x); - } - catch (InvocationTargetException x) - { - throw (InternalError)new InternalError().initCause(x); - } } protected final synchronized void setDefinition(Object[] array) { - if(frozen) + if(frozen || definition != null) { throw new IllegalStateException("Annotation properties have already been defined"); } - frozen = true; - // TODO consider checking that the type matches - // (or better yet (?), remove the first two redundant elements from the array) - decodeValues(values, annotationType, annotationType.getClassLoader(), array); + definition = array; } @ikvm.lang.Internal - public Map getValues() + public final Map getValues() { return values; } @ikvm.lang.Internal - public synchronized void freeze() + public final synchronized void freeze() { if(!frozen) { frozen = true; - setDefaults(values, annotationType); + if(values == null) + { + values = new HashMap<String, Object>(); + } + if(definition == null) + { + setDefaults(values, annotationType); + } + else + { + // TODO consider checking that the type matches + // (or better yet (?), remove the first two redundant elements from the array) + decodeValues(values, annotationType, annotationType.getClassLoader(), definition); + definition = null; + } } } @@ -251,8 +259,7 @@ public abstract class AnnotationAttributeBase } catch (NoSuchMethodException x) { - // TODO this probably isn't the right exception - throw new IncompatibleClassChangeError("Method " + name + " is missing in annotation " + annotationClass.getName()); + // ignore values for members that are no longer present } } setDefaults(map, annotationClass); @@ -273,15 +280,7 @@ public abstract class AnnotationAttributeBase private static Class classFromSig(ClassLoader loader, String name) { - if (name.startsWith("L") && name.endsWith(";")) - { - name = name.substring(1, name.length() - 1).replace('/', '.'); - } - else if (name.startsWith("[")) - { - name = name.replace('/', '.'); - } - else if (name.length() == 1) + if (name.length() == 1) { switch (name.charAt(0)) { @@ -304,9 +303,23 @@ public abstract class AnnotationAttributeBase case 'V': return Void.TYPE; default: - throw new TypeNotPresentException(name, null); + throw new GenericSignatureFormatError(); } } + + if (!isValidTypeSig(name, 0, name.length())) + { + throw new GenericSignatureFormatError(); + } + + if (name.charAt(0) == 'L') + { + name = name.substring(1, name.length() - 1).replace('/', '.'); + } + else // must be an array then + { + name = name.replace('/', '.'); + } try { return Class.forName(name, false, loader); @@ -317,6 +330,41 @@ public abstract class AnnotationAttributeBase } } + private static boolean isValidTypeSig(String sig, int start, int end) + { + if (start >= end) + { + return false; + } + switch (sig.charAt(start)) + { + case 'L': + return sig.indexOf(';', start + 1) == end - 1; + case '[': + while (sig.charAt(start) == '[') + { + start++; + if (start == end) + { + return false; + } + } + return isValidTypeSig(sig, start, end); + case 'B': + case 'Z': + case 'C': + case 'S': + case 'I': + case 'J': + case 'F': + case 'D': + return start == end - 1; + default: + return false; + } + } + + @ikvm.lang.Internal public static Object newAnnotation(ClassLoader loader, Object definition) { Object[] array = (Object[])definition; @@ -328,6 +376,10 @@ public abstract class AnnotationAttributeBase if (classNameOrClass instanceof String) { annotationClass = classFromSig(loader, (String)classNameOrClass); + if (!annotationClass.isAnnotation()) + { + return null; + } array[1] = annotationClass; } else @@ -339,6 +391,7 @@ public abstract class AnnotationAttributeBase return Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class<?>[] { annotationClass }, newAnnotationInvocationHandler(annotationClass, map)); } + @ikvm.lang.Internal public static Object decodeElementValue(Object obj, Class type, ClassLoader loader) throws IllegalAccessException { @@ -348,7 +401,10 @@ public abstract class AnnotationAttributeBase try { Object[] error = (Object[])obj; - t = (Throwable)Class.forName((String)error[1]).getConstructor(String.class).newInstance(error[2]); + Class exception = Class.forName((String)error[1]); + t = (Throwable)(error.length == 2 + ? exception.newInstance() + : exception.getConstructor(String.class).newInstance(error[2])); } catch (Exception x) { @@ -398,7 +454,14 @@ public abstract class AnnotationAttributeBase byte tag = CIL.unbox_byte(array[0]); if (tag != 'c') throw new ClassCastException(); - return classFromSig(loader, (String)array[1]); + try + { + return classFromSig(loader, (String)array[1]); + } + catch (TypeNotPresentException x) + { + return new TypeNotPresentExceptionProxy(x.typeName(), x); + } } else if (type.isArray()) { @@ -410,21 +473,34 @@ public abstract class AnnotationAttributeBase Object dst = Array.newInstance(type, array.length - 1); for (int i = 0; i < array.length - 1; i++) { - Array.set(dst, i, decodeElementValue(array[i + 1], type, loader)); + Object val = decodeElementValue(array[i + 1], type, loader); + try + { + Array.set(dst, i, val); + } + catch (IllegalArgumentException _) + { + // JDKBUG emulate JDK bug + throw new ArrayStoreException(val.getClass().getName()); + } } return dst; } - else if (type.isAnnotation()) - { - return type.cast(newAnnotation(loader, obj)); - } else if (type.isEnum()) { Object[] array = (Object[])obj; byte tag = CIL.unbox_byte(array[0]); if (tag != 'e') throw new ClassCastException(); - Class enumClass = classFromSig(loader, (String)array[1]); + Class enumClass; + try + { + enumClass = classFromSig(loader, (String)array[1]); + } + catch (TypeNotPresentException x) + { + return new TypeNotPresentExceptionProxy(x.typeName(), x); + } try { return Enum.valueOf(enumClass, (String)array[2]); @@ -434,32 +510,29 @@ public abstract class AnnotationAttributeBase throw new EnumConstantNotPresentException(enumClass, (String)array[2]); } } - else + else // must be an annotation then { - throw new ClassCastException(); + Object ann = newAnnotation(loader, obj); + if (!type.isInstance(ann)) + { + // JDKBUG if newAnnotation() returns null (because the class is not an annotation), + // the next line will throw a NullPointerException (similar to the JDK) + return newAnnotationTypeMismatchExceptionProxy(ann.getClass() + "[" + ann + "]"); + } + return ann; } } - protected final Object writeReplace() + private final Object writeReplace() { + freeze(); return Proxy.newProxyInstance(annotationType.getClassLoader(), new Class[] { annotationType }, newAnnotationInvocationHandler(annotationType, values)); } - private static cli.System.Reflection.ConstructorInfo annotationInvocationHandlerConstructor; - - private static InvocationHandler newAnnotationInvocationHandler(Class type, Map memberValues) - { - if (annotationInvocationHandlerConstructor == null) - { - cli.System.Type typeofClass = cli.System.Type.GetType("java.lang.Class"); - cli.System.Type typeofMap = cli.System.Type.GetType("java.util.Map"); - annotationInvocationHandlerConstructor = cli.System.Type.GetType("sun.reflect.annotation.AnnotationInvocationHandler") - .GetConstructor(BindingFlags.wrap(BindingFlags.Instance | BindingFlags.NonPublic), null, new cli.System.Type[] { typeofClass, typeofMap }, null); - } - return (InvocationHandler)annotationInvocationHandlerConstructor.Invoke(new Object[] { type, memberValues }); - } + private static native InvocationHandler newAnnotationInvocationHandler(Class type, Map memberValues); + private static native Object newAnnotationTypeMismatchExceptionProxy(String msg); public final Class<? extends Annotation> annotationType() { @@ -468,16 +541,19 @@ public abstract class AnnotationAttributeBase public final boolean Equals(Object o) { + freeze(); return equals(annotationType, values, o); } public final int GetHashCode() { + freeze(); return hashCode(annotationType, values); } public final String ToString() { + freeze(); return toString(annotationType, values); } diff --git a/external/ikvm/openjdk/ikvm/internal/Winsock.java b/external/ikvm/openjdk/ikvm/internal/Winsock.java index 86cbb8527c..ce05de0305 100644 --- a/external/ikvm/openjdk/ikvm/internal/Winsock.java +++ b/external/ikvm/openjdk/ikvm/internal/Winsock.java @@ -122,6 +122,7 @@ public final class Winsock public static final int SO_RCVBUF = SocketOptionName.ReceiveBuffer; public static final int SO_KEEPALIVE = SocketOptionName.KeepAlive; public static final int SO_REUSEADDR = SocketOptionName.ReuseAddress; + public static final int SO_EXCLUSIVEADDRUSE = SocketOptionName.ExclusiveAddressUse; public static final int SO_BROADCAST = SocketOptionName.Broadcast; public static final int SO_RCVTIMEO = SocketOptionName.ReceiveTimeout; public static final int SO_ERROR = SocketOptionName.Error; diff --git a/external/ikvm/openjdk/java/awt/image/BufferedImage.java b/external/ikvm/openjdk/java/awt/image/BufferedImage.java index 33c9c2701e..ee00c6a819 100644 --- a/external/ikvm/openjdk/java/awt/image/BufferedImage.java +++ b/external/ikvm/openjdk/java/awt/image/BufferedImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,8 @@ import java.awt.geom.Rectangle2D; import java.awt.geom.Point2D; import java.awt.Point; import java.awt.Rectangle; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.Vector; @@ -425,6 +427,7 @@ public class BufferedImage extends java.awt.Image colorModel = cm; this.imageType = imageType; this.currentBuffer = BUFFER_RASTER; + raster.getDataBuffer().setImage( this ); } /** @@ -469,7 +472,7 @@ public class BufferedImage extends java.awt.Image WritableRaster raster, boolean isRasterPremultiplied, Hashtable<?,?> properties) { - + if (!cm.isCompatibleRaster(raster)) { throw new IllegalArgumentException("Raster "+raster+ @@ -486,10 +489,12 @@ public class BufferedImage extends java.awt.Image colorModel = cm; this.raster = raster; + raster.getDataBuffer().setImage( this ); this.currentBuffer = BUFFER_RASTER; this.properties = properties; int numBands = raster.getNumBands(); boolean isAlphaPre = cm.isAlphaPremultiplied(); + final boolean isStandard = isStandard(cm, raster); ColorSpace cs; // Force the raster data alpha state to match the premultiplied @@ -500,8 +505,9 @@ public class BufferedImage extends java.awt.Image cs = cm.getColorSpace(); int csType = cs.getType(); if (csType != ColorSpace.TYPE_RGB) { - if (csType == ColorSpace.TYPE_GRAY - && cm instanceof ComponentColorModel) { + if (csType == ColorSpace.TYPE_GRAY && + isStandard && + cm instanceof ComponentColorModel) { // Check if this might be a child raster (fix for bug 4240596) if (sm instanceof ComponentSampleModel && ((ComponentSampleModel)sm).getPixelStride() != numBands) { @@ -531,6 +537,7 @@ public class BufferedImage extends java.awt.Image // are correct int pixSize = cm.getPixelSize(); if (iraster.getPixelStride() == 1 && + isStandard && cm instanceof DirectColorModel && (pixSize == 32 || pixSize == 24)) { @@ -563,6 +570,7 @@ public class BufferedImage extends java.awt.Image } // if (iraster.getPixelStride() == 1 } // ((raster instanceof IntegerComponentRaster) && else if ((cm instanceof IndexColorModel) && (numBands == 1) && + isStandard && (!cm.hasAlpha() || !isAlphaPre)) { IndexColorModel icm = (IndexColorModel) cm; @@ -580,6 +588,7 @@ public class BufferedImage extends java.awt.Image } // else if (cm instanceof IndexColorModel) && (numBands == 1)) else if ((raster instanceof ShortComponentRaster) && (cm instanceof DirectColorModel) + && isStandard && (numBands == 3) && !cm.hasAlpha()) { @@ -599,6 +608,7 @@ public class BufferedImage extends java.awt.Image } // else if ((cm instanceof IndexColorModel) && (numBands == 1)) else if ((raster instanceof ByteComponentRaster) && (cm instanceof ComponentColorModel) + && isStandard && (raster.getSampleModel() instanceof PixelInterleavedSampleModel) && (numBands == 3 || numBands == 4)) { @@ -623,14 +633,15 @@ public class BufferedImage extends java.awt.Image } } if (is8bit && + braster.getPixelStride() == numBands && offs[0] == numBands-1 && offs[1] == numBands-2 && offs[2] == numBands-3) { - if (numBands == 3) { + if (numBands == 3 && !ccm.hasAlpha()) { imageType = TYPE_3BYTE_BGR; } - else if (offs[3] == 0) { + else if (offs[3] == 0 && ccm.hasAlpha()) { imageType = (isAlphaPre ? TYPE_4BYTE_ABGR_PRE : TYPE_4BYTE_ABGR); @@ -638,6 +649,27 @@ public class BufferedImage extends java.awt.Image } } // else if ((raster instanceof ByteComponentRaster) && } + + private static boolean isStandard(ColorModel cm, WritableRaster wr) { + final Class<? extends ColorModel> cmClass = cm.getClass(); + final Class<? extends WritableRaster> wrClass = wr.getClass(); + final Class<? extends SampleModel> smClass = wr.getSampleModel().getClass(); + + final PrivilegedAction<Boolean> checkClassLoadersAction = + new PrivilegedAction<Boolean>() + { + + @Override + public Boolean run() { + final ClassLoader std = System.class.getClassLoader(); + + return (cmClass.getClassLoader() == std) && + (smClass.getClassLoader() == std) && + (wrClass.getClassLoader() == std); + } + }; + return AccessController.doPrivileged(checkClassLoadersAction); + } /** * Get the .NET Bitmap object. @@ -649,6 +681,23 @@ public class BufferedImage extends java.awt.Image } /** + * Switch to the BITMAP buffer and invalidate the RASTER buffer before a graphics operation. + */ + final void toBitmap(){ + raster2Bitmap(); + currentBuffer = BUFFER_BITMAP; + } + + /** + * Switch to the RASTER buffer and invalidate the BITMAP buffer before a graphics operation. + */ + @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation + final void toRaster() { + bitmap2Raster(); + currentBuffer = BUFFER_RASTER; + } + + /** * This Implementation of BufferedImage has 2 different Buffer, * a Java WritableRaster and a .NET Bitmap. * This method convert a Java WritableRaster to a .NET Bitmap if needed. @@ -714,21 +763,23 @@ public class BufferedImage extends java.awt.Image } if(raster == null){ raster = createRaster(width, height); + raster.getDataBuffer().setImage( this ); } + this.currentBuffer = BUFFER_BOTH; switch (getType()){ case TYPE_INT_ARGB: copyFromBitmap(bitmap, ((DataBufferInt)raster.getDataBuffer()).getData()); break; default: + Object pixel = colorModel.getDataElements( 0, null ); //allocate a buffer for the follow loop for( int y = 0; y<height; y++){ for(int x = 0; x<width; x++){ int rgb = bitmap.GetPixel(x, y).ToArgb(); - raster.setDataElements(x, y, colorModel.getDataElements(rgb, null)); + raster.setDataElements(x, y, colorModel.getDataElements(rgb, pixel)); } } } - this.currentBuffer = BUFFER_BOTH; } } @@ -1192,7 +1243,7 @@ public class BufferedImage extends java.awt.Image * pixels for this image. * @see ImageProducer */ - public ImageProducer getSource(){ + public ImageProducer getSource() { if(currentBuffer != BUFFER_RASTER){ synchronized( bitmap ) { int width = bitmap.get_Width(); @@ -1281,10 +1332,9 @@ public class BufferedImage extends java.awt.Image * image. */ public Graphics2D createGraphics() { - ikvm.awt.IkvmToolkit toolkit = ikvm.awt.IkvmToolkit.DefaultToolkit.get(); - raster2Bitmap(); - this.currentBuffer = BUFFER_BITMAP; - return toolkit.createGraphics( bitmap ); + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + return env.createGraphics(this); } /** @@ -1346,9 +1396,9 @@ public class BufferedImage extends java.awt.Image * <code>BufferedImage</code>. */ public String toString() { - return new String("BufferedImage@"+Integer.toHexString(hashCode()) - +": type = "+imageType - +" "+colorModel+" "+raster); + return "BufferedImage@"+Integer.toHexString(hashCode()) + +": type = "+imageType + +" "+colorModel+" "+raster; } /** diff --git a/external/ikvm/openjdk/java/awt/image/IndexColorModel.java b/external/ikvm/openjdk/java/awt/image/IndexColorModel.java index 34ab79d68c..b76f924c23 100644 --- a/external/ikvm/openjdk/java/awt/image/IndexColorModel.java +++ b/external/ikvm/openjdk/java/awt/image/IndexColorModel.java @@ -618,7 +618,7 @@ public class IndexColorModel extends ColorModel { } nBits[0] = nBits[1] = nBits[2] = 8; } - return nBits; + return nBits.clone(); } /** @@ -1501,6 +1501,14 @@ public class IndexColorModel extends ColorModel { } /** + * Disposes of system resources associated with this + * <code>ColorModel</code> once this <code>ColorModel</code> is no + * longer referenced. + */ + public void finalize() { + } + + /** * Returns the <code>String</code> representation of the contents of * this <code>ColorModel</code>object. * @return a <code>String</code> representing the contents of this diff --git a/external/ikvm/openjdk/java/io/FileInputStream.java b/external/ikvm/openjdk/java/io/FileInputStream.java index a0bc2247eb..3547947f07 100644 --- a/external/ikvm/openjdk/java/io/FileInputStream.java +++ b/external/ikvm/openjdk/java/io/FileInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package java.io; import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl; +import sun.misc.IoTrace; /** @@ -51,6 +52,9 @@ class FileInputStream extends InputStream /* File Descriptor - handle to the open file */ private final FileDescriptor fd; + /* The path of the referenced file (null if the stream is created with a file descriptor) */ + private final String path; + private FileChannel channel = null; private final Object closeLock = new Object(); @@ -133,8 +137,14 @@ class FileInputStream extends InputStream if (name == null) { throw new NullPointerException(); } + /* + if (file.isInvalid()) { + throw new FileNotFoundException("Invalid file path"); + } + */ fd = new FileDescriptor(); fd.incrementAndGetUseCount(); + this.path = name; open(name); } @@ -171,6 +181,7 @@ class FileInputStream extends InputStream security.checkRead(fdObj); } fd = fdObj; + path = null; /* * FileDescriptor is being shared by streams. @@ -197,9 +208,15 @@ class FileInputStream extends InputStream * file is reached. * @exception IOException if an I/O error occurs. */ - public int read() throws IOException - { - return fd.read(); + public int read() throws IOException { + Object traceContext = IoTrace.fileReadBegin(path); + int b = 0; + try { + b = fd.read(); + } finally { + IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1); + } + return b; } /** @@ -226,7 +243,14 @@ class FileInputStream extends InputStream * @exception IOException if an I/O error occurs. */ public int read(byte b[]) throws IOException { - return readBytes(b, 0, b.length); + Object traceContext = IoTrace.fileReadBegin(path); + int bytesRead = 0; + try { + bytesRead = readBytes(b, 0, b.length); + } finally { + IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead); + } + return bytesRead; } /** @@ -248,7 +272,14 @@ class FileInputStream extends InputStream * @exception IOException if an I/O error occurs. */ public int read(byte b[], int off, int len) throws IOException { - return readBytes(b, off, len); + Object traceContext = IoTrace.fileReadBegin(path); + int bytesRead = 0; + try { + bytesRead = readBytes(b, off, len); + } finally { + IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead); + } + return bytesRead; } /** @@ -376,7 +407,7 @@ class FileInputStream extends InputStream public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, true, false, this); + channel = FileChannelImpl.open(fd, path, true, false, this); /* * Increment fd's use count. Invoking the channel's close() diff --git a/external/ikvm/openjdk/java/io/FileOutputStream.java b/external/ikvm/openjdk/java/io/FileOutputStream.java index e931fe6823..dae9d4bc5e 100644 --- a/external/ikvm/openjdk/java/io/FileOutputStream.java +++ b/external/ikvm/openjdk/java/io/FileOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package java.io; import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl; +import sun.misc.IoTrace; /** @@ -58,6 +59,11 @@ class FileOutputStream extends OutputStream private final FileDescriptor fd; /** + * The path of the referenced file (null if the stream is created with a file descriptor) + */ + private final String path; + + /** * True if the file is opened for append. */ private final boolean append; @@ -205,9 +211,14 @@ class FileOutputStream extends OutputStream if (name == null) { throw new NullPointerException(); } + /* + if (file.isInvalid()) { + throw new FileNotFoundException("Invalid file path"); + } + */ this.fd = new FileDescriptor(); this.append = append; - + this.path = name; fd.incrementAndGetUseCount(); open(name, append); } @@ -244,6 +255,7 @@ class FileOutputStream extends OutputStream security.checkWrite(fdObj); } this.fd = fdObj; + this.path = null; this.append = false; /* @@ -287,7 +299,14 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(int b) throws IOException { - write(b, append); + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + write(b, append); + bytesWritten = 1; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -312,7 +331,14 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(byte b[]) throws IOException { - writeBytes(b, 0, b.length, append); + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + writeBytes(b, 0, b.length, append); + bytesWritten = b.length; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -325,7 +351,14 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(byte b[], int off, int len) throws IOException { - writeBytes(b, off, len, append); + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + writeBytes(b, off, len, append); + bytesWritten = len; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -408,7 +441,7 @@ class FileOutputStream extends OutputStream public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, false, true, append, this); + channel = FileChannelImpl.open(fd, path, false, true, append, this); /* * Increment fd's use count. Invoking the channel's close() diff --git a/external/ikvm/openjdk/java/io/ObjectStreamClass.java b/external/ikvm/openjdk/java/io/ObjectStreamClass.java index 7cca355287..97489b1eb8 100644 --- a/external/ikvm/openjdk/java/io/ObjectStreamClass.java +++ b/external/ikvm/openjdk/java/io/ObjectStreamClass.java @@ -50,7 +50,10 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import sun.misc.Unsafe; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; import sun.reflect.ReflectionFactory; +import sun.reflect.misc.ReflectUtil; /** * Serialization's descriptor for classes. It contains the name and @@ -262,7 +265,17 @@ public class ObjectStreamClass implements Serializable { * * @return the <code>Class</code> instance that this descriptor represents */ + @CallerSensitive public Class<?> forClass() { + if (cl == null) { + return null; + } + if (System.getSecurityManager() != null) { + Class<?> caller = Reflection.getCallerClass(); + if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) { + ReflectUtil.checkPackageAccess(cl); + } + } return cl; } @@ -1156,7 +1169,14 @@ public class ObjectStreamClass implements Serializable { end = end.getSuperclass(); } + HashSet<String> oscNames = new HashSet<>(3); + for (ObjectStreamClass d = this; d != null; d = d.superDesc) { + if (oscNames.contains(d.name)) { + throw new InvalidClassException("Circular reference."); + } else { + oscNames.add(d.name); + } // search up inheritance hierarchy for class with matching name String searchName = (d.cl != null) ? d.cl.getName() : d.name; @@ -1848,8 +1868,10 @@ public class ObjectStreamClass implements Serializable { private final ObjectStreamField[] fields; /** number of primitive fields */ private final int numPrimFields; - /** unsafe field keys */ - private final long[] keys; + /** unsafe field keys for reading fields - may contain dupes */ + private final long[] readKeys; + /** unsafe fields keys for writing fields - no dupes */ + private final long[] writeKeys; /** field data offsets */ private final int[] offsets; /** field type codes */ @@ -1867,16 +1889,22 @@ public class ObjectStreamClass implements Serializable { FieldReflector(ObjectStreamField[] fields) { this.fields = fields; int nfields = fields.length; - keys = new long[nfields]; + readKeys = new long[nfields]; + writeKeys = new long[nfields]; offsets = new int[nfields]; typeCodes = new char[nfields]; ArrayList<Class<?>> typeList = new ArrayList<>(); + Set<Long> usedKeys = new HashSet<>(); + for (int i = 0; i < nfields; i++) { ObjectStreamField f = fields[i]; Field rf = f.getField(); - keys[i] = (rf != null) ? + long key = (rf != null) ? unsafe.objectFieldOffset(rf) : Unsafe.INVALID_FIELD_OFFSET; + readKeys[i] = key; + writeKeys[i] = usedKeys.add(key) ? + key : Unsafe.INVALID_FIELD_OFFSET; offsets[i] = f.getOffset(); typeCodes[i] = f.getTypeCode(); if (!f.isPrimitive()) { @@ -1912,7 +1940,7 @@ public class ObjectStreamClass implements Serializable { * in array should be equal to Unsafe.INVALID_FIELD_OFFSET. */ for (int i = 0; i < numPrimFields; i++) { - long key = keys[i]; + long key = readKeys[i]; int off = offsets[i]; switch (typeCodes[i]) { case 'Z': @@ -1963,7 +1991,7 @@ public class ObjectStreamClass implements Serializable { throw new NullPointerException(); } for (int i = 0; i < numPrimFields; i++) { - long key = keys[i]; + long key = writeKeys[i]; if (key == Unsafe.INVALID_FIELD_OFFSET) { continue; // discard value } @@ -2024,7 +2052,7 @@ public class ObjectStreamClass implements Serializable { switch (typeCodes[i]) { case 'L': case '[': - vals[offsets[i]] = unsafe.getObject(obj, keys[i]); + vals[offsets[i]] = unsafe.getObject(obj, readKeys[i]); break; default: @@ -2045,7 +2073,7 @@ public class ObjectStreamClass implements Serializable { throw new NullPointerException(); } for (int i = numPrimFields; i < fields.length; i++) { - long key = keys[i]; + long key = writeKeys[i]; if (key == Unsafe.INVALID_FIELD_OFFSET) { continue; // discard value } @@ -2148,7 +2176,7 @@ public class ObjectStreamClass implements Serializable { } } - private static native Object getFastFieldReflector(Object fields); + private static native Object getFastFieldReflector(ObjectStreamField[] fields); /** * FieldReflector cache lookup key. Keys are considered equal if they diff --git a/external/ikvm/openjdk/java/io/ObjectStreamField.java b/external/ikvm/openjdk/java/io/ObjectStreamField.java index c2d1ffe174..1d7c2cdf1e 100644 --- a/external/ikvm/openjdk/java/io/ObjectStreamField.java +++ b/external/ikvm/openjdk/java/io/ObjectStreamField.java @@ -26,6 +26,9 @@ package java.io; import java.lang.reflect.Field; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; +import sun.reflect.misc.ReflectUtil; /** * A description of a Serializable field from a Serializable class. An array @@ -163,7 +166,14 @@ public class ObjectStreamField * @return a <code>Class</code> object representing the type of the * serializable field */ + @CallerSensitive public Class<?> getType() { + if (System.getSecurityManager() != null) { + Class<?> caller = Reflection.getCallerClass(); + if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) { + ReflectUtil.checkPackageAccess(type); + } + } return type; } diff --git a/external/ikvm/openjdk/java/io/RandomAccessFile.java b/external/ikvm/openjdk/java/io/RandomAccessFile.java index 3cddafd2f4..61fc27a7e4 100644 --- a/external/ikvm/openjdk/java/io/RandomAccessFile.java +++ b/external/ikvm/openjdk/java/io/RandomAccessFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package java.io; import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl; +import sun.misc.IoTrace; /** @@ -62,6 +63,9 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { private FileChannel channel = null; private boolean rw; + /* The path of the referenced file */ + private final String path; + private Object closeLock = new Object(); private volatile boolean closed = false; @@ -228,8 +232,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { if (name == null) { throw new NullPointerException(); } + /* + if (file.isInvalid()) { + throw new FileNotFoundException("Invalid file path"); + } + */ fd = new FileDescriptor(); fd.incrementAndGetUseCount(); + this.path = name; open(name, imode); } @@ -267,7 +277,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { public final FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, true, rw, this); + channel = FileChannelImpl.open(fd, path, true, rw, this); /* * FileDescriptor could be shared by FileInputStream or @@ -325,9 +335,15 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * @exception IOException if an I/O error occurs. Not thrown if * end-of-file has been reached. */ - public int read() throws IOException - { - return fd.read(); + public int read() throws IOException { + Object traceContext = IoTrace.fileReadBegin(path); + int b = 0; + try { + b = fd.read(); + } finally { + IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1); + } + return b; } /** @@ -339,7 +355,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { */ private int readBytes(byte b[], int off, int len) throws IOException { - return fd.readBytes(b, off, len); + Object traceContext = IoTrace.fileReadBegin(path); + int bytesRead = 0; + try { + bytesRead = fd.readBytes(b, off, len); + } finally { + IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead); + } + return bytesRead; } /** @@ -479,9 +502,15 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * @param b the <code>byte</code> to be written. * @exception IOException if an I/O error occurs. */ - public void write(int b) throws IOException - { - fd.write(b); + public void write(int b) throws IOException { + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + fd.write(b); + bytesWritten = 1; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -492,9 +521,15 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * @param len the number of bytes that are written * @exception IOException If an I/O error has occurred. */ - private void writeBytes(byte b[], int off, int len) throws IOException - { - fd.writeBytes(b, off, len); + private void writeBytes(byte b[], int off, int len) throws IOException { + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + fd.writeBytes(b, off, len); + bytesWritten = len; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** diff --git a/external/ikvm/openjdk/java/lang/Class.java b/external/ikvm/openjdk/java/lang/Class.java index 20f35534c3..bbc1d241f6 100644 --- a/external/ikvm/openjdk/java/lang/Class.java +++ b/external/ikvm/openjdk/java/lang/Class.java @@ -53,6 +53,7 @@ import java.util.Set; import java.util.Map; import java.util.HashMap; import sun.misc.Unsafe; +import sun.reflect.CallerSensitive; import sun.reflect.ConstantPool; import sun.reflect.Reflection; import sun.reflect.ReflectionFactory; @@ -65,7 +66,9 @@ import sun.reflect.generics.repository.ConstructorRepository; import sun.reflect.generics.scope.ClassScope; import sun.security.util.SecurityConstants; import java.lang.annotation.Annotation; -import sun.reflect.annotation.AnnotationType; +import java.lang.reflect.Proxy; +import sun.reflect.annotation.*; +import sun.reflect.misc.ReflectUtil; import cli.System.Runtime.Serialization.IObjectReference; import cli.System.Runtime.Serialization.SerializationException; import cli.System.Runtime.Serialization.SerializationInfo; @@ -281,10 +284,11 @@ public final * by this method fails * @exception ClassNotFoundException if the class cannot be located */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Class<?> forName(String className) throws ClassNotFoundException { - return forName0(className, true, ClassLoader.getCallerClassLoader()); + return forName0(className, true, + ClassLoader.getClassLoader(Reflection.getCallerClass())); } @@ -348,7 +352,7 @@ public final * @see java.lang.ClassLoader * @since 1.2 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException @@ -356,7 +360,7 @@ public final if (loader == null) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = ClassLoader.getCallerClassLoader(); + ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass()); if (ccl != null) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); @@ -418,19 +422,14 @@ public final * </ul> * */ - @ikvm.internal.HasCallerID + @CallerSensitive public T newInstance() throws InstantiationException, IllegalAccessException { if (System.getSecurityManager() != null) { - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false); } - return newInstance0(ikvm.internal.CallerID.getCallerID()); - } - private T newInstance0(ikvm.internal.CallerID callerID) - throws InstantiationException, IllegalAccessException - { // NOTE: the following code may not be strictly correct under // the current Java memory model. @@ -464,7 +463,7 @@ public final // Security check (same as in java.lang.reflect.Constructor) int modifiers = tmpConstructor.getModifiers(); if (!Reflection.quickCheckMemberAccess(this, modifiers)) { - Class<?> caller = callerID.getCallerClass(); + Class<?> caller = Reflection.getCallerClass(); if (newInstanceCallerCache != caller) { Reflection.ensureMemberAccess(caller, this, null, modifiers); newInstanceCallerCache = caller; @@ -705,17 +704,14 @@ public final * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission */ - @ikvm.internal.HasCallerID + @CallerSensitive public ClassLoader getClassLoader() { ClassLoader cl = getClassLoader0(); if (cl == null) return null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = ClassLoader.getCallerClassLoader(); - if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass()); } return cl; } @@ -996,6 +992,7 @@ public final * that class is a local or anonymous class; otherwise {@code null}. * @since 1.5 */ + @CallerSensitive public Method getEnclosingMethod() { EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); @@ -1017,13 +1014,22 @@ public final for(int i = 0; i < parameterClasses.length; i++) parameterClasses[i] = toClass(parameterTypes[i]); + // Perform access check + Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass(); + // be very careful not to change the stack depth of this + // checkMemberAccess call for security reasons + // see java.lang.SecurityManager.checkMemberAccess + // + // Note that we need to do this on the enclosing class + enclosingCandidate.checkMemberAccess(Member.DECLARED, + Reflection.getCallerClass(), true); /* * Loop over all declared methods; match method name, * number of and type of parameters, *and* return * type. Matching return type is also necessary * because of covariant returns, etc. */ - for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) { + for(Method m: enclosingCandidate.getDeclaredMethods()) { if (m.getName().equals(enclosingInfo.getName()) ) { Class<?>[] candidateParamClasses = m.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { @@ -1124,6 +1130,7 @@ public final * that class is a local or anonymous class; otherwise {@code null}. * @since 1.5 */ + @CallerSensitive public Constructor<?> getEnclosingConstructor() { EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); @@ -1144,11 +1151,20 @@ public final for(int i = 0; i < parameterClasses.length; i++) parameterClasses[i] = toClass(parameterTypes[i]); + // Perform access check + Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass(); + // be very careful not to change the stack depth of this + // checkMemberAccess call for security reasons + // see java.lang.SecurityManager.checkMemberAccess + // + // Note that we need to do this on the enclosing class + enclosingCandidate.checkMemberAccess(Member.DECLARED, + Reflection.getCallerClass(), true); /* * Loop over all declared constructors; match number * of and type of parameters. */ - for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) { + for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) { Class<?>[] candidateParamClasses = c.getParameterTypes(); if (candidateParamClasses.length == parameterClasses.length) { boolean matches = true; @@ -1190,6 +1206,7 @@ public final * @return the immediately enclosing class of the underlying class * @since 1.5 */ + @CallerSensitive public Class<?> getEnclosingClass() { // There are five kinds of classes (or interfaces): // a) Top level classes @@ -1203,18 +1220,24 @@ public final // attribute if and only if it is a local class or an // anonymous class. EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); + Class<?> enclosingCandidate; if (enclosingInfo == null) { // This is a top level or a nested class or an inner class (a, b, or c) - return getDeclaringClass(); + enclosingCandidate = getDeclaringClass(); } else { Class<?> enclosingClass = enclosingInfo.getEnclosingClass(); // This is a local class or an anonymous class (d or e) if (enclosingClass == this || enclosingClass == null) throw new InternalError("Malformed enclosing method information"); else - return enclosingClass; + enclosingCandidate = enclosingClass; } + + if (enclosingCandidate != null) + enclosingCandidate.checkPackageAccess( + ClassLoader.getClassLoader(Reflection.getCallerClass()), true); + return enclosingCandidate; } /** @@ -1397,12 +1420,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Class<?>[] getClasses() { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false); // Privileged so this implementation can look at DECLARED classes, // something the caller might not have privilege to do. The code here @@ -1473,12 +1496,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field[] getFields() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyFields(privateGetPublicFields(null)); } @@ -1525,12 +1548,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method[] getMethods() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyMethods(privateGetPublicMethods()); } @@ -1575,12 +1598,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<?>[] getConstructors() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyConstructors(privateGetDeclaredConstructors(true)); } @@ -1634,13 +1657,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field getField(String name) throws NoSuchFieldException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); Field field = getField0(name); if (field == null) { throw new NoSuchFieldException(name); @@ -1720,13 +1743,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); Method method = getMethod0(name, parameterTypes); if (method == null) { throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); @@ -1775,13 +1798,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return getConstructor0(parameterTypes, Member.PUBLIC); } @@ -1819,12 +1842,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Class<?>[] getDeclaredClasses() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false); return getDeclaredClasses0(); } @@ -1864,12 +1887,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field[] getDeclaredFields() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return copyFields(privateGetDeclaredFields(false)); } @@ -1913,12 +1936,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method[] getDeclaredMethods() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return copyMethods(privateGetDeclaredMethods(false)); } @@ -1959,12 +1982,12 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<?>[] getDeclaredConstructors() throws SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return copyConstructors(privateGetDeclaredConstructors(false)); } @@ -2003,13 +2026,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); Field field = searchFields(privateGetDeclaredFields(false), name); if (field == null) { throw new NoSuchFieldException(name); @@ -2059,13 +2082,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); if (method == null) { throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); @@ -2110,13 +2133,13 @@ public final * * @since JDK1.1 */ - @ikvm.internal.HasCallerID + @CallerSensitive public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { // be very careful not to change the stack depth of this // checkMemberAccess call for security reasons // see java.lang.SecurityManager.checkMemberAccess - checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); + checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return getConstructor0(parameterTypes, Member.DECLARED); } @@ -2274,31 +2297,69 @@ public final */ static native Class getPrimitiveClass(String name); + private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) { + if (smgr.getClass() == SecurityManager.class) return false; + + Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class}; + return smgr.getClass().getMethod0("checkMemberAccess", paramTypes). + getDeclaringClass() != SecurityManager.class; + } + /* * Check if client is allowed to access members. If access is denied, * throw a SecurityException. * - * Be very careful not to change the stack depth of this checkMemberAccess - * call for security reasons. - * See java.lang.SecurityManager.checkMemberAccess. + * This method also enforces package access. * * <p> Default policy: allow all clients access with normal Java access * control. */ - private void checkMemberAccess(int which, ClassLoader ccl) { - SecurityManager s = System.getSecurityManager(); + private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) { + final SecurityManager s = System.getSecurityManager(); if (s != null) { - s.checkMemberAccess(this, which); - ClassLoader cl = getClassLoader0(); - if ((ccl != null) && (ccl != cl) && - ((cl == null) || !cl.isAncestor(ccl))) { + final ClassLoader ccl = ClassLoader.getClassLoader(caller); + final ClassLoader cl = getClassLoader0(); + if (!isCheckMemberAccessOverridden(s)) { + // Inlined SecurityManager.checkMemberAccess + if (which != Member.PUBLIC) { + if (ccl != cl) { + s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); + } + } + } else { + // Don't refactor; otherwise break the stack depth for + // checkMemberAccess of subclasses of SecurityManager as specified. + s.checkMemberAccess(this, which); + } + this.checkPackageAccess(ccl, checkProxyInterfaces); + } + } + + /* + * Checks if a client loaded in ClassLoader ccl is allowed to access this + * class under the current package access policy. If access is denied, + * throw a SecurityException. + */ + private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) { + final SecurityManager s = System.getSecurityManager(); + if (s != null) { + final ClassLoader cl = getClassLoader0(); + if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) { String name = this.getName(); int i = name.lastIndexOf('.'); if (i != -1) { - s.checkPackageAccess(name.substring(0, i)); + // skip the package access check on a proxy class in default proxy package + String pkg = name.substring(0, i); + if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) { + s.checkPackageAccess(pkg); + } } } + // check package access on the proxy interfaces + if (checkProxyInterfaces && Proxy.isProxyClass(this)) { + ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces()); + } } } diff --git a/external/ikvm/openjdk/java/lang/ClassLoader.java b/external/ikvm/openjdk/java/lang/ClassLoader.java index 8162ba81c0..57c1ee3e39 100644 --- a/external/ikvm/openjdk/java/lang/ClassLoader.java +++ b/external/ikvm/openjdk/java/lang/ClassLoader.java @@ -56,6 +56,7 @@ import sun.misc.CompoundEnumeration; import sun.misc.Resource; import sun.misc.URLClassPath; import sun.misc.VM; +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.security.util.SecurityConstants; @@ -1256,9 +1257,11 @@ public abstract class ClassLoader { * * @since 1.7 */ - @ikvm.internal.HasCallerID + @CallerSensitive protected static boolean registerAsParallelCapable() { - return ParallelLoaders.register(ikvm.internal.CallerID.getCallerID().getCallerClass()); + Class<? extends ClassLoader> callerClass = + Reflection.getCallerClass().asSubclass(ClassLoader.class); + return ParallelLoaders.register(callerClass); } /** @@ -1402,15 +1405,13 @@ public abstract class ClassLoader { * * @since 1.2 */ + @CallerSensitive public final ClassLoader getParent() { if (parent == null) return null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = getCallerClassLoader(); - if (ccl != null && !isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + checkClassLoaderPermission(parent, Reflection.getCallerClass()); } return parent; } @@ -1470,7 +1471,7 @@ public abstract class ClassLoader { * * @revised 1.4 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static ClassLoader getSystemClassLoader() { initSystemClassLoader(); if (scl == null) { @@ -1478,10 +1479,7 @@ public abstract class ClassLoader { } SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = getCallerClassLoader(); - if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + checkClassLoaderPermission(scl, Reflection.getCallerClass()); } return scl; } @@ -1529,13 +1527,25 @@ public abstract class ClassLoader { return false; } - // Returns the invoker's class loader, or null if none. - // NOTE: This must always be invoked when there is exactly one intervening - // frame from the core libraries on the stack between this method's - // invocation and the desired invoker. - static ClassLoader getCallerClassLoader() { - // NOTE use of more generic Reflection.getCallerClass() - Class caller = Reflection.getCallerClass(3); + // Tests if class loader access requires "getClassLoader" permission + // check. A class loader 'from' can access class loader 'to' if + // class loader 'from' is same as class loader 'to' or an ancestor + // of 'to'. The class loader in a system domain can access + // any class loader. + private static boolean needsClassLoaderPermissionCheck(ClassLoader from, + ClassLoader to) + { + if (from == to) + return false; + + if (from == null) + return false; + + return !to.isAncestor(from); + } + + // Returns the class's class loader, or null if none. + static ClassLoader getClassLoader(Class<?> caller) { // This can be null if the VM is requesting it if (caller == null) { return null; @@ -1544,6 +1554,17 @@ public abstract class ClassLoader { return caller.getClassLoader0(); } + static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + // caller can be null if the VM is requesting it + ClassLoader ccl = getClassLoader(caller); + if (needsClassLoaderPermissionCheck(ccl, cl)) { + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); + } + } + } + // The class loader for the system // @GuardedBy("ClassLoader.class") private static ClassLoader scl; diff --git a/external/ikvm/openjdk/java/lang/Package.java b/external/ikvm/openjdk/java/lang/Package.java new file mode 100644 index 0000000000..395cf3365e --- /dev/null +++ b/external/ikvm/openjdk/java/lang/Package.java @@ -0,0 +1,615 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +import java.io.InputStream; +import java.util.Enumeration; + +import java.util.StringTokenizer; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URL; +import java.net.MalformedURLException; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import java.util.jar.JarInputStream; +import java.util.jar.Manifest; +import java.util.jar.Attributes; +import java.util.jar.Attributes.Name; +import java.util.jar.JarException; +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; + +import java.lang.annotation.Annotation; +import sun.net.www.ParseUtil; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; + +/** + * {@code Package} objects contain version information + * about the implementation and specification of a Java package. + * This versioning information is retrieved and made available + * by the {@link ClassLoader} instance that + * loaded the class(es). Typically, it is stored in the manifest that is + * distributed with the classes. + * + * <p>The set of classes that make up the package may implement a + * particular specification and if so the specification title, version number, + * and vendor strings identify that specification. + * An application can ask if the package is + * compatible with a particular version, see the {@link + * #isCompatibleWith isCompatibleWith} + * method for details. + * + * <p>Specification version numbers use a syntax that consists of nonnegative + * decimal integers separated by periods ".", for example "2.0" or + * "1.2.3.4.5.6.7". This allows an extensible number to be used to represent + * major, minor, micro, etc. versions. The version specification is described + * by the following formal grammar: + * <blockquote> + * <dl> + * <dt><i>SpecificationVersion: + * <dd>Digits RefinedVersion<sub>opt</sub></i> + + * <p><dt><i>RefinedVersion:</i> + * <dd>{@code .} <i>Digits</i> + * <dd>{@code .} <i>Digits RefinedVersion</i> + * + * <p><dt><i>Digits: + * <dd>Digit + * <dd>Digits</i> + * + * <p><dt><i>Digit:</i> + * <dd>any character for which {@link Character#isDigit} returns {@code true}, + * e.g. 0, 1, 2, ... + * </dl> + * </blockquote> + * + * <p>The implementation title, version, and vendor strings identify an + * implementation and are made available conveniently to enable accurate + * reporting of the packages involved when a problem occurs. The contents + * all three implementation strings are vendor specific. The + * implementation version strings have no specified syntax and should + * only be compared for equality with desired version identifiers. + * + * <p>Within each {@code ClassLoader} instance all classes from the same + * java package have the same Package object. The static methods allow a package + * to be found by name or the set of all packages known to the current class + * loader to be found. + * + * @see ClassLoader#definePackage + */ +public class Package implements java.lang.reflect.AnnotatedElement { + /** + * Return the name of this package. + * + * @return The fully-qualified name of this package as defined in section 6.5.3 of + * <cite>The Java™ Language Specification</cite>, + * for example, {@code java.lang} + */ + public String getName() { + return pkgName; + } + + + /** + * Return the title of the specification that this package implements. + * @return the specification title, null is returned if it is not known. + */ + public String getSpecificationTitle() { + return specTitle; + } + + /** + * Returns the version number of the specification + * that this package implements. + * This version string must be a sequence of nonnegative decimal + * integers separated by "."'s and may have leading zeros. + * When version strings are compared the most significant + * numbers are compared. + * @return the specification version, null is returned if it is not known. + */ + public String getSpecificationVersion() { + return specVersion; + } + + /** + * Return the name of the organization, vendor, + * or company that owns and maintains the specification + * of the classes that implement this package. + * @return the specification vendor, null is returned if it is not known. + */ + public String getSpecificationVendor() { + return specVendor; + } + + /** + * Return the title of this package. + * @return the title of the implementation, null is returned if it is not known. + */ + public String getImplementationTitle() { + return implTitle; + } + + /** + * Return the version of this implementation. It consists of any string + * assigned by the vendor of this implementation and does + * not have any particular syntax specified or expected by the Java + * runtime. It may be compared for equality with other + * package version strings used for this implementation + * by this vendor for this package. + * @return the version of the implementation, null is returned if it is not known. + */ + public String getImplementationVersion() { + return implVersion; + } + + /** + * Returns the name of the organization, + * vendor or company that provided this implementation. + * @return the vendor that implemented this package.. + */ + public String getImplementationVendor() { + return implVendor; + } + + /** + * Returns true if this package is sealed. + * + * @return true if the package is sealed, false otherwise + */ + public boolean isSealed() { + return sealBase != null; + } + + /** + * Returns true if this package is sealed with respect to the specified + * code source url. + * + * @param url the code source url + * @return true if this package is sealed with respect to url + */ + public boolean isSealed(URL url) { + return url.equals(sealBase); + } + + /** + * Compare this package's specification version with a + * desired version. It returns true if + * this packages specification version number is greater than or equal + * to the desired version number. <p> + * + * Version numbers are compared by sequentially comparing corresponding + * components of the desired and specification strings. + * Each component is converted as a decimal integer and the values + * compared. + * If the specification value is greater than the desired + * value true is returned. If the value is less false is returned. + * If the values are equal the period is skipped and the next pair of + * components is compared. + * + * @param desired the version string of the desired version. + * @return true if this package's version number is greater + * than or equal to the desired version number + * + * @exception NumberFormatException if the desired or current version + * is not of the correct dotted form. + */ + public boolean isCompatibleWith(String desired) + throws NumberFormatException + { + if (specVersion == null || specVersion.length() < 1) { + throw new NumberFormatException("Empty version string"); + } + + String [] sa = specVersion.split("\\.", -1); + int [] si = new int[sa.length]; + for (int i = 0; i < sa.length; i++) { + si[i] = Integer.parseInt(sa[i]); + if (si[i] < 0) + throw NumberFormatException.forInputString("" + si[i]); + } + + String [] da = desired.split("\\.", -1); + int [] di = new int[da.length]; + for (int i = 0; i < da.length; i++) { + di[i] = Integer.parseInt(da[i]); + if (di[i] < 0) + throw NumberFormatException.forInputString("" + di[i]); + } + + int len = Math.max(di.length, si.length); + for (int i = 0; i < len; i++) { + int d = (i < di.length ? di[i] : 0); + int s = (i < si.length ? si[i] : 0); + if (s < d) + return false; + if (s > d) + return true; + } + return true; + } + + /** + * Find a package by name in the callers {@code ClassLoader} instance. + * The callers {@code ClassLoader} instance is used to find the package + * instance corresponding to the named class. If the callers + * {@code ClassLoader} instance is null then the set of packages loaded + * by the system {@code ClassLoader} instance is searched to find the + * named package. <p> + * + * Packages have attributes for versions and specifications only if the class + * loader created the package instance with the appropriate attributes. Typically, + * those attributes are defined in the manifests that accompany the classes. + * + * @param name a package name, for example, java.lang. + * @return the package of the requested name. It may be null if no package + * information is available from the archive or codebase. + */ + @CallerSensitive + public static Package getPackage(String name) { + ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass()); + if (l != null) { + return l.getPackage(name); + } else { + return getSystemPackage(name); + } + } + + /** + * Get all the packages currently known for the caller's {@code ClassLoader} + * instance. Those packages correspond to classes loaded via or accessible by + * name to that {@code ClassLoader} instance. If the caller's + * {@code ClassLoader} instance is the bootstrap {@code ClassLoader} + * instance, which may be represented by {@code null} in some implementations, + * only packages corresponding to classes loaded by the bootstrap + * {@code ClassLoader} instance will be returned. + * + * @return a new array of packages known to the callers {@code ClassLoader} + * instance. An zero length array is returned if none are known. + */ + @CallerSensitive + public static Package[] getPackages() { + ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass()); + if (l != null) { + return l.getPackages(); + } else { + return getSystemPackages(); + } + } + + /** + * Get the package for the specified class. + * The class's class loader is used to find the package instance + * corresponding to the specified class. If the class loader + * is the bootstrap class loader, which may be represented by + * {@code null} in some implementations, then the set of packages + * loaded by the bootstrap class loader is searched to find the package. + * <p> + * Packages have attributes for versions and specifications only + * if the class loader created the package + * instance with the appropriate attributes. Typically those + * attributes are defined in the manifests that accompany + * the classes. + * + * @param class the class to get the package of. + * @return the package of the class. It may be null if no package + * information is available from the archive or codebase. */ + static Package getPackage(Class<?> c) { + String name = c.getName(); + int i = name.lastIndexOf('.'); + if (i != -1) { + name = name.substring(0, i); + ClassLoader cl = c.getClassLoader(); + if (cl != null) { + return cl.getPackage(name); + } else { + return getSystemPackage(name); + } + } else { + return null; + } + } + + /** + * Return the hash code computed from the package name. + * @return the hash code computed from the package name. + */ + public int hashCode(){ + return pkgName.hashCode(); + } + + /** + * Returns the string representation of this Package. + * Its value is the string "package " and the package name. + * If the package title is defined it is appended. + * If the package version is defined it is appended. + * @return the string representation of the package. + */ + public String toString() { + String spec = specTitle; + String ver = specVersion; + if (spec != null && spec.length() > 0) + spec = ", " + spec; + else + spec = ""; + if (ver != null && ver.length() > 0) + ver = ", version " + ver; + else + ver = ""; + return "package " + pkgName + spec + ver; + } + + private Class<?> getPackageInfo() { + if (packageInfo == null) { + try { + packageInfo = Class.forName(pkgName + ".package-info", false, loader); + } catch (ClassNotFoundException ex) { + // store a proxy for the package info that has no annotations + class PackageInfoProxy {} + packageInfo = PackageInfoProxy.class; + } + } + return packageInfo; + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.5 + */ + public <A extends Annotation> A getAnnotation(Class<A> annotationClass) { + return getPackageInfo().getAnnotation(annotationClass); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.5 + */ + public boolean isAnnotationPresent( + Class<? extends Annotation> annotationClass) { + return getPackageInfo().isAnnotationPresent(annotationClass); + } + + /** + * @since 1.5 + */ + public Annotation[] getAnnotations() { + return getPackageInfo().getAnnotations(); + } + + /** + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() { + return getPackageInfo().getDeclaredAnnotations(); + } + + /** + * Construct a package instance with the specified version + * information. + * @param pkgName the name of the package + * @param spectitle the title of the specification + * @param specversion the version of the specification + * @param specvendor the organization that maintains the specification + * @param impltitle the title of the implementation + * @param implversion the version of the implementation + * @param implvendor the organization that maintains the implementation + * @return a new package for containing the specified information. + */ + Package(String name, + String spectitle, String specversion, String specvendor, + String impltitle, String implversion, String implvendor, + URL sealbase, ClassLoader loader) + { + pkgName = name; + implTitle = impltitle; + implVersion = implversion; + implVendor = implvendor; + specTitle = spectitle; + specVersion = specversion; + specVendor = specvendor; + sealBase = sealbase; + this.loader = loader; + } + + /* + * Construct a package using the attributes from the specified manifest. + * + * @param name the package name + * @param man the optional manifest for the package + * @param url the optional code source url for the package + */ + private Package(String name, Manifest man, URL url, ClassLoader loader) { + String path = name.replace('.', '/').concat("/"); + String sealed = null; + String specTitle= null; + String specVersion= null; + String specVendor= null; + String implTitle= null; + String implVersion= null; + String implVendor= null; + URL sealBase= null; + Attributes attr = man.getAttributes(path); + if (attr != null) { + specTitle = attr.getValue(Name.SPECIFICATION_TITLE); + specVersion = attr.getValue(Name.SPECIFICATION_VERSION); + specVendor = attr.getValue(Name.SPECIFICATION_VENDOR); + implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE); + implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION); + implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR); + sealed = attr.getValue(Name.SEALED); + } + attr = man.getMainAttributes(); + if (attr != null) { + if (specTitle == null) { + specTitle = attr.getValue(Name.SPECIFICATION_TITLE); + } + if (specVersion == null) { + specVersion = attr.getValue(Name.SPECIFICATION_VERSION); + } + if (specVendor == null) { + specVendor = attr.getValue(Name.SPECIFICATION_VENDOR); + } + if (implTitle == null) { + implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE); + } + if (implVersion == null) { + implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION); + } + if (implVendor == null) { + implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR); + } + if (sealed == null) { + sealed = attr.getValue(Name.SEALED); + } + } + if ("true".equalsIgnoreCase(sealed)) { + sealBase = url; + } + pkgName = name; + this.specTitle = specTitle; + this.specVersion = specVersion; + this.specVendor = specVendor; + this.implTitle = implTitle; + this.implVersion = implVersion; + this.implVendor = implVendor; + this.sealBase = sealBase; + this.loader = loader; + } + + /* + * Returns the loaded system package for the specified name. + */ + static Package getSystemPackage(String name) { + synchronized (pkgs) { + Package pkg = pkgs.get(name); + if (pkg == null) { + name = name.replace('.', '/').concat("/"); + String fn = getSystemPackage0(name); + if (fn != null) { + pkg = defineSystemPackage(name, fn); + } + } + return pkg; + } + } + + /* + * Return an array of loaded system packages. + */ + static Package[] getSystemPackages() { + // First, update the system package map with new package names + String[] names = getSystemPackages0(); + synchronized (pkgs) { + for (int i = 0; i < names.length; i++) { + defineSystemPackage(names[i], getSystemPackage0(names[i])); + } + return pkgs.values().toArray(new Package[pkgs.size()]); + } + } + + private static Package defineSystemPackage(final String iname, + final String fn) + { + return AccessController.doPrivileged(new PrivilegedAction<Package>() { + public Package run() { + String name = iname; + // Get the cached code source url for the file name + URL url = urls.get(fn); + if (url == null) { + // URL not found, so create one + File file = new File(fn); + try { + url = ParseUtil.fileToEncodedURL(file); + } catch (MalformedURLException e) { + } + if (url != null) { + urls.put(fn, url); + // If loading a JAR file, then also cache the manifest + if (file.isFile()) { + mans.put(fn, loadManifest(fn)); + } + } + } + // Convert to "."-separated package name + name = name.substring(0, name.length() - 1).replace('/', '.'); + Package pkg; + Manifest man = mans.get(fn); + if (man != null) { + pkg = new Package(name, man, url, null); + } else { + pkg = new Package(name, null, null, null, + null, null, null, null, null); + } + pkgs.put(name, pkg); + return pkg; + } + }); + } + + /* + * Returns the Manifest for the specified JAR file name. + */ + private static Manifest loadManifest(String fn) { + try (FileInputStream fis = new FileInputStream(fn); + JarInputStream jis = new JarInputStream(fis, false)) + { + return jis.getManifest(); + } catch (IOException e) { + return null; + } + } + + // The map of loaded system packages + private static Map<String, Package> pkgs = new HashMap<>(31); + + // Maps each directory or zip file name to its corresponding url + private static Map<String, URL> urls = new HashMap<>(10); + + // Maps each code source url for a jar file to its manifest + private static Map<String, Manifest> mans = new HashMap<>(10); + + private static native String getSystemPackage0(String name); + private static native String[] getSystemPackages0(); + + /* + * Private storage for the package name and attributes. + */ + private final String pkgName; + private final String specTitle; + private final String specVersion; + private final String specVendor; + private final String implTitle; + private final String implVersion; + private final String implVendor; + private final URL sealBase; + private transient final ClassLoader loader; + private transient Class packageInfo; +} diff --git a/external/ikvm/openjdk/java/lang/System.java b/external/ikvm/openjdk/java/lang/System.java index e6f4d3cc02..e74187b9d3 100644 --- a/external/ikvm/openjdk/java/lang/System.java +++ b/external/ikvm/openjdk/java/lang/System.java @@ -33,7 +33,7 @@ import java.security.PrivilegedAction; import java.security.AllPermission; import java.nio.channels.Channel; import java.nio.channels.spi.SelectorProvider; - +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.security.util.SecurityConstants; @@ -1105,9 +1105,9 @@ public final class System { * @see java.lang.Runtime#load(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static void load(String filename) { - Runtime.getRuntime().load0(Reflection.getCallerClass(2), filename); + Runtime.getRuntime().load0(Reflection.getCallerClass(), filename); } /** @@ -1131,9 +1131,9 @@ public final class System { * @see java.lang.Runtime#loadLibrary(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static void loadLibrary(String libname) { - Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(2), libname); + Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname); } /** @@ -1160,7 +1160,6 @@ public final class System { return "lib" + libname + ".so"; } } - /* returns the class of the caller. */ static Class<?> getCallerClass() { // NOTE use of more generic Reflection.getCallerClass() diff --git a/external/ikvm/openjdk/java/lang/Thread.java b/external/ikvm/openjdk/java/lang/Thread.java index 3de50ff741..e8f57d065a 100644 --- a/external/ikvm/openjdk/java/lang/Thread.java +++ b/external/ikvm/openjdk/java/lang/Thread.java @@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.LockSupport; import sun.nio.ch.Interruptible; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; import sun.security.util.SecurityConstants; @@ -169,7 +171,7 @@ class Thread implements Runnable { private cli.System.Threading.Thread nativeThread; private Throwable stillborn; private boolean running; // used only for coordination with stop0(), is never set to false - private boolean interruptPending; + private volatile boolean interruptPending; private volatile boolean nativeInterruptPending; private volatile boolean interruptableWait; private boolean timedWait; @@ -1228,7 +1230,12 @@ class Thread implements Runnable { * @revised 6.0 */ public static boolean interrupted() { - return currentThread().isInterrupted(true); + Thread current = currentThread(); + if (!current.interruptPending) { + return false; + } + current.interruptPending = false; + return true; } /** @@ -1245,22 +1252,7 @@ class Thread implements Runnable { * @revised 6.0 */ public boolean isInterrupted() { - return isInterrupted(false); - } - - /** - * Tests if some Thread has been interrupted. The interrupted state - * is reset or not based on the value of ClearInterrupted that is - * passed. - */ - private boolean isInterrupted(boolean ClearInterrupted) { - synchronized (lock) { - boolean b = interruptPending; - if (ClearInterrupted) { - interruptPending = false; - } - return b; - } + return interruptPending; } /** @@ -1723,19 +1715,18 @@ class Thread implements Runnable { * * @since 1.2 */ + @CallerSensitive public ClassLoader getContextClassLoader() { if (contextClassLoader == ClassLoader.DUMMY) { contextClassLoader = ClassLoader.getSystemClassLoader(); } if (contextClassLoader == null) return null; + SecurityManager sm = System.getSecurityManager(); if (sm != null) { - ClassLoader ccl = ClassLoader.getCallerClassLoader(); - if (ccl != null && ccl != contextClassLoader && - !contextClassLoader.isAncestor(ccl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + ClassLoader.checkClassLoaderPermission(contextClassLoader, + Reflection.getCallerClass()); } return contextClassLoader; } diff --git a/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java b/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java index 710d6ab077..6f0db408fa 100644 --- a/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java +++ b/external/ikvm/openjdk/java/lang/invoke/MethodHandles.java @@ -33,11 +33,10 @@ import sun.invoke.util.Wrapper; import java.util.List; import java.util.ArrayList; import java.util.Arrays; +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; -import ikvm.internal.CallerID; -import ikvm.internal.HasCallerID; /** * This class consists exclusively of static methods that operate on or return @@ -68,9 +67,9 @@ public class MethodHandles { * This lookup object is a <em>capability</em> which may be delegated to trusted agents. * Do not store it in place where untrusted code can access it. */ - @HasCallerID + @CallerSensitive public static Lookup lookup() { - return new Lookup(CallerID.getCallerID()); + return new Lookup(Reflection.getCallerClass()); } /** @@ -412,14 +411,9 @@ public class MethodHandles { * Also, don't make it private, lest javac interpose * an access$N method. */ - Lookup(CallerID caller) { - this(caller.getCallerClass(), ALL_MODES); - // make sure we haven't accidentally picked up a privileged class: - checkUnprivilegedlookupClass(lookupClass); - } - Lookup(Class<?> lookupClass) { this(lookupClass, ALL_MODES); + checkUnprivilegedlookupClass(lookupClass); } private Lookup(Class<?> lookupClass, int allowedModes) { diff --git a/external/ikvm/openjdk/java/lang/reflect/Constructor.java b/external/ikvm/openjdk/java/lang/reflect/Constructor.java index e62e87728d..b13d30a543 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Constructor.java +++ b/external/ikvm/openjdk/java/lang/reflect/Constructor.java @@ -25,6 +25,7 @@ package java.lang.reflect; +import sun.reflect.CallerSensitive; import sun.reflect.ConstructorAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.ConstructorRepository; @@ -501,15 +502,14 @@ public final * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public T newInstance(Object ... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = Reflection.getCallerClass(2); - + Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, null, modifiers); } } diff --git a/external/ikvm/openjdk/java/lang/reflect/Field.java b/external/ikvm/openjdk/java/lang/reflect/Field.java index c796d20a1f..b2cb46b3f0 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Field.java +++ b/external/ikvm/openjdk/java/lang/reflect/Field.java @@ -25,6 +25,7 @@ package java.lang.reflect; +import sun.reflect.CallerSensitive; import sun.reflect.FieldAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.FieldRepository; @@ -34,7 +35,6 @@ import sun.reflect.generics.scope.ClassScope; import java.lang.annotation.Annotation; import java.util.Map; import sun.reflect.annotation.AnnotationParser; -import ikvm.internal.CallerID; /** @@ -365,11 +365,16 @@ class Field extends AccessibleObject implements Member { * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).get(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).get(obj); } /** @@ -394,11 +399,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getBoolean(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getBoolean(obj); } /** @@ -423,11 +433,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getByte(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getByte(obj); } /** @@ -454,11 +469,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getChar(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getChar(obj); } /** @@ -485,11 +505,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getShort(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getShort(obj); } /** @@ -516,11 +541,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public int getInt(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getInt(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getInt(obj); } /** @@ -547,11 +577,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getLong(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getLong(obj); } /** @@ -578,11 +613,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getFloat(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getFloat(obj); } /** @@ -609,11 +649,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getDouble(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getDouble(obj); } /** @@ -682,11 +727,16 @@ class Field extends AccessibleObject implements Member { * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).set(obj, value); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).set(obj, value); } /** @@ -713,11 +763,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setBoolean(Object obj, boolean z) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setBoolean(obj, z); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setBoolean(obj, z); } /** @@ -744,11 +799,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setByte(Object obj, byte b) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setByte(obj, b); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setByte(obj, b); } /** @@ -775,11 +835,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setChar(Object obj, char c) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setChar(obj, c); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setChar(obj, c); } /** @@ -806,11 +871,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setShort(Object obj, short s) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setShort(obj, s); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setShort(obj, s); } /** @@ -837,11 +907,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setInt(Object obj, int i) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setInt(obj, i); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setInt(obj, i); } /** @@ -868,11 +943,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setLong(Object obj, long l) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setLong(obj, l); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setLong(obj, l); } /** @@ -899,11 +979,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setFloat(Object obj, float f) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setFloat(obj, f); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setFloat(obj, f); } /** @@ -930,21 +1015,25 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setDouble(Object obj, double d) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setDouble(obj, d); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setDouble(obj, d); } - // Convenience routine which performs security checks - private FieldAccessor getFieldAccessor(Object obj, CallerID callerID) + // security check is done before calling this method + private FieldAccessor getFieldAccessor(Object obj) throws IllegalAccessException { - doSecurityCheck(obj, callerID); boolean ov = override; - FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor; - return (a != null)? a : acquireFieldAccessor(ov); + FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor; + return (a != null) ? a : acquireFieldAccessor(ov); } // NOTE that there is no synchronization used here. It is correct @@ -989,19 +1078,6 @@ class Field extends AccessibleObject implements Member { } } - // NOTE: be very careful if you change the stack depth of this - // routine. The depth of the "getCallerClass" call is hardwired so - // that the compiler can have an easier time if this gets inlined. - private void doSecurityCheck(Object obj, CallerID callerID) throws IllegalAccessException { - if (!override) { - if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = callerID.getCallerClass(); - - checkAccess(caller, clazz, obj, modifiers); - } - } - } - /* * Utility routine to paper over array type names */ diff --git a/external/ikvm/openjdk/java/lang/reflect/Method.java b/external/ikvm/openjdk/java/lang/reflect/Method.java index b1548d6bbe..dce789a4f1 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Method.java +++ b/external/ikvm/openjdk/java/lang/reflect/Method.java @@ -26,6 +26,7 @@ package java.lang.reflect; import ikvm.internal.CallerID; +import sun.reflect.CallerSensitive; import sun.reflect.MethodAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.MethodRepository; @@ -578,15 +579,14 @@ public final * @exception ExceptionInInitializerError if the initialization * provoked by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = CallerID.getCallerID().getCallerClass(); - + Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers); } } diff --git a/external/ikvm/openjdk/java/lang/reflect/Proxy.java b/external/ikvm/openjdk/java/lang/reflect/Proxy.java index d4a391f738..3d9850e032 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Proxy.java +++ b/external/ikvm/openjdk/java/lang/reflect/Proxy.java @@ -27,6 +27,9 @@ package java.lang.reflect; import java.lang.ref.Reference; import java.lang.ref.WeakReference; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -36,6 +39,10 @@ import java.util.Set; import java.util.List; import java.util.WeakHashMap; import sun.misc.ProxyGenerator; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; +import sun.reflect.misc.ReflectUtil; +import sun.security.util.SecurityConstants; /** * {@code Proxy} provides static methods for creating dynamic proxy @@ -265,9 +272,67 @@ public class Proxy implements java.io.Serializable { * @param h the invocation handler for this proxy instance */ protected Proxy(InvocationHandler h) { + doNewInstanceCheck(); this.h = h; } + private static class ProxyAccessHelper { + // The permission is implementation specific. + static final Permission PROXY_PERMISSION = + new ReflectPermission("proxyConstructorNewInstance"); + // These system properties are defined to provide a short-term + // workaround if customers need to disable the new security checks. + static final boolean allowNewInstance; + static final boolean allowNullLoader; + static { + allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance"); + allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader"); + } + + private static boolean getBooleanProperty(final String key) { + String s = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { + return System.getProperty(key); + } + }); + return Boolean.valueOf(s); + } + + static boolean needsNewInstanceCheck(Class<?> proxyClass) { + if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) { + return false; + } + + if (ReflectUtil.isNonPublicProxyClass(proxyClass)) { + for (Class<?> intf : proxyClass.getInterfaces()) { + if (!Modifier.isPublic(intf.getModifiers())) { + return true; + } + } + } + return false; + } + } + + /* + * Access check on a proxy class that implements any non-public interface. + * + * @throws SecurityException if a security manager exists, and + * the caller does not have the permission. + */ + private void doNewInstanceCheck() { + SecurityManager sm = System.getSecurityManager(); + Class<?> proxyClass = this.getClass(); + if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) { + try { + sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION); + } catch (SecurityException e) { + throw new SecurityException("Not allowed to construct a Proxy " + + "instance that implements a non-public interface", e); + } + } + } + /** * Returns the {@code java.lang.Class} object for a proxy class * given a class loader and an array of interfaces. The proxy class @@ -342,10 +407,59 @@ public class Proxy implements java.io.Serializable { * @throws NullPointerException if the {@code interfaces} array * argument or any of its elements are {@code null} */ + @CallerSensitive public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); + } + + return getProxyClass0(loader, interfaces); + } + + /* + * Check permissions required to create a Proxy class. + * + * To define a proxy class, it performs the access checks as in + * Class.forName (VM will invoke ClassLoader.checkPackageAccess): + * 1. "getClassLoader" permission check if loader == null + * 2. checkPackageAccess on the interfaces it implements + * + * To get a constructor and new instance of a proxy class, it performs + * the package access check on the interfaces it implements + * as in Class.getConstructor. + * + * If an interface is non-public, the proxy class must be defined by + * the defining loader of the interface. If the caller's class loader + * is not the same as the defining loader of the interface, the VM + * will throw IllegalAccessError when the generated proxy class is + * being defined via the defineClass0 method. + */ + private static void checkProxyAccess(Class<?> caller, + ClassLoader loader, + Class<?>... interfaces) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + ClassLoader ccl = caller.getClassLoader(); + if (loader == null && ccl != null) { + if (!ProxyAccessHelper.allowNullLoader) { + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); + } + } + ReflectUtil.checkProxyPackageAccess(ccl, interfaces); + } + } + + /** + * Generate a proxy class. Must call the checkProxyAccess method + * to perform permission checks before calling this. + */ + private static Class<?> getProxyClass0(ClassLoader loader, + Class<?>... interfaces) { if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } @@ -497,8 +611,9 @@ public class Proxy implements java.io.Serializable { } } - if (proxyPkg == null) { // if no non-public proxy interfaces, - proxyPkg = ""; // use the unnamed package + if (proxyPkg == null) { + // if no non-public proxy interfaces, use com.sun.proxy package + proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; } generate: do @@ -592,6 +707,7 @@ generate: do * if the invocation handler, {@code h}, is * {@code null} */ + @CallerSensitive public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) @@ -601,25 +717,50 @@ generate: do throw new NullPointerException(); } + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); + } + /* * Look up or generate the designated proxy class. */ - Class<?> cl = getProxyClass(loader, interfaces); + Class<?> cl = getProxyClass0(loader, interfaces); /* * Invoke its constructor with the designated invocation handler. */ try { - Constructor cons = cl.getConstructor(constructorParams); - return cons.newInstance(new Object[] { h }); + final Constructor<?> cons = cl.getConstructor(constructorParams); + final InvocationHandler ih = h; + if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { + // create proxy instance with doPrivilege as the proxy class may + // implement non-public interfaces that requires a special permission + return AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + return newInstance(cons, ih); + } + }); + } else { + return newInstance(cons, ih); + } } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); - } catch (IllegalAccessException e) { - throw new InternalError(e.toString()); - } catch (InstantiationException e) { + } + } + + private static Object newInstance(Constructor<?> cons, InvocationHandler h) { + try { + return cons.newInstance(new Object[] {h} ); + } catch (IllegalAccessException | InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { - throw new InternalError(e.toString()); + Throwable t = e.getCause(); + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else { + throw new InternalError(t.toString()); + } } } diff --git a/external/ikvm/openjdk/java/net/DefaultDatagramSocketImplFactory.java b/external/ikvm/openjdk/java/net/DefaultDatagramSocketImplFactory.java index c08fba397a..7d4f8edba7 100644 --- a/external/ikvm/openjdk/java/net/DefaultDatagramSocketImplFactory.java +++ b/external/ikvm/openjdk/java/net/DefaultDatagramSocketImplFactory.java @@ -56,20 +56,34 @@ class DefaultDatagramSocketImplFactory /* If the version supports a dual stack TCP implementation */ private static boolean useDualStackImpl = false; + /* sun.net.useExclusiveBind */ + private static String exclBindProp; + + /* True if exclusive binding is on for Windows */ + private static boolean exclusiveBind = true; + + static { // Determine Windows Version. - java.security.AccessController.doPrivileged( new PrivilegedAction<Object>() { - public Object run() { - version = 0; - try { - version = Float.parseFloat(System.getProperties().getProperty("os.version")); - preferIPv4Stack = Boolean.parseBoolean( - System.getProperties().getProperty("java.net.preferIPv4Stack")); - } catch (NumberFormatException e ) { - assert false : e; + java.security.AccessController.doPrivileged( + new PrivilegedAction<Object>() { + public Object run() { + version = 0; + try { + version = Float.parseFloat(System.getProperties() + .getProperty("os.version")); + preferIPv4Stack = Boolean.parseBoolean( + System.getProperties() + .getProperty( + "java.net.preferIPv4Stack")); + exclBindProp = System.getProperty( + "sun.net.useExclusiveBind"); + } catch (NumberFormatException e ) { + assert false : e; + } + return null; // nothing to return } - return null; // nothing to return - } }); + }); String ipv6 = ikvm.internal.Util.SafeGetEnvironmentVariable("IKVM_IPV6"); if (ipv6 != null) { @@ -87,7 +101,14 @@ class DefaultDatagramSocketImplFactory // (version >= 6.0) implies Vista or greater. if (version >= 6.0 && !preferIPv4Stack) { - useDualStackImpl = true; + useDualStackImpl = true; + } + if (exclBindProp != null) { + // sun.net.useExclusiveBind is true + exclusiveBind = exclBindProp.length() == 0 ? true + : Boolean.parseBoolean(exclBindProp); + } else if (version < 6.0) { + exclusiveBind = false; } // impl.prefix @@ -119,10 +140,12 @@ class DefaultDatagramSocketImplFactory throw new SocketException("can't instantiate DatagramSocketImpl"); } } else { + if (isMulticast) + exclusiveBind = false; if (useDualStackImpl && !isMulticast) - return new DualStackPlainDatagramSocketImpl(); + return new DualStackPlainDatagramSocketImpl(exclusiveBind); else - return new TwoStacksPlainDatagramSocketImpl(); + return new TwoStacksPlainDatagramSocketImpl(exclusiveBind); } } } diff --git a/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl.java b/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl.java index dddc50cca0..1d74e28c71 100644 --- a/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl.java +++ b/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl.java @@ -42,6 +42,22 @@ import java.io.IOException; class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl { + // true if this socket is exclusively bound + private final boolean exclusiveBind; + + /* + * Set to true if SO_REUSEADDR is set after the socket is bound to + * indicate SO_REUSEADDR is being emulated + */ + private boolean reuseAddressEmulated; + + // emulates SO_REUSEADDR when exclusiveBind is true and socket is bound + private boolean isReuseAddress; + + DualStackPlainDatagramSocketImpl(boolean exclBind) { + exclusiveBind = exclBind; + } + protected void datagramSocketCreate() throws SocketException { if (fd == null) throw new SocketException("Socket closed"); @@ -58,7 +74,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl if (laddr == null) throw new NullPointerException("argument address"); - socketBind(nativefd, laddr, lport); + socketBind(nativefd, laddr, lport, exclusiveBind); if (lport == 0) { localPort = socketLocalPort(nativefd); } else { @@ -138,6 +154,7 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl fd.setSocket(null); } + @SuppressWarnings("fallthrough") protected void socketSetOption(int opt, Object val) throws SocketException { cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); @@ -150,6 +167,13 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl optionValue = ((Integer)val).intValue(); break; case SO_REUSEADDR : + if (exclusiveBind && localPort != 0) { + // socket already bound, emulate SO_REUSEADDR + reuseAddressEmulated = true; + isReuseAddress = (Boolean)val; + return; + } + //Intentional fallthrough case SO_BROADCAST : optionValue = ((Boolean)val).booleanValue() ? 1 : 0; break; @@ -167,6 +191,8 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl if (opt == SO_BINDADDR) { return socketLocalAddress(nativefd); } + if (opt == SO_REUSEADDR && reuseAddressEmulated) + return isReuseAddress; int value = socketGetIntOption(nativefd, opt); Object returnValue = null; @@ -237,10 +263,10 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl return ret; } - private static void socketBind(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport) - throws SocketException { + private static void socketBind(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, + int localport, boolean exclBind) throws SocketException { ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); - DualStackPlainDatagramSocketImpl_c.socketBind(env, fd, localAddress, localport); + DualStackPlainDatagramSocketImpl_c.socketBind(env, fd, localAddress, localport, exclBind); env.ThrowPendingException(); } diff --git a/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java b/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java index 5abb1109ae..1f4ed69bef 100644 --- a/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java +++ b/external/ikvm/openjdk/java/net/DualStackPlainDatagramSocketImpl_c.java @@ -127,7 +127,7 @@ static cli.System.Net.Sockets.Socket socketCreate * Signature: (ILjava/net/InetAddress;I)V */ static void socketBind - (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) { + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port, boolean exclBind) { SOCKETADDRESS sa; sa = new SOCKETADDRESS(); int rv; @@ -136,8 +136,7 @@ static void socketBind JNI_TRUE) != 0) { return; } - - rv = bind(fd, sa); + rv = NET_WinBind(fd, sa, exclBind); if (rv == SOCKET_ERROR) { if (WSAGetLastError() == WSAEACCES) { @@ -275,7 +274,7 @@ static int socketReceiveOrPeekData } fullPacket = (char *)malloc(packetBufferLen); if (!fullPacket) { - JNU_ThrowOutOfMemoryError(env, "heap allocation failed"); + JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); return -1; } } else { @@ -424,7 +423,7 @@ static void socketSend } fullPacket = (char *)malloc(length); if (!fullPacket) { - JNU_ThrowOutOfMemoryError(env, "heap allocation failed"); + JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); return; } } else { diff --git a/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java b/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java index 4f35a6c6f6..a3584d8632 100644 --- a/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java +++ b/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl.java @@ -34,15 +34,25 @@ import java.io.FileDescriptor; * single file descriptor. * * @author Chris Hegarty - * @author Jeroen Frijters */ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl { - public DualStackPlainSocketImpl() {} - public DualStackPlainSocketImpl(FileDescriptor fd) { + + // true if this socket is exclusively bound + private final boolean exclusiveBind; + + // emulates SO_REUSEADDR when exclusiveBind is true + private boolean isReuseAddress; + + public DualStackPlainSocketImpl(boolean exclBind) { + exclusiveBind = exclBind; + } + + public DualStackPlainSocketImpl(FileDescriptor fd, boolean exclBind) { this.fd = fd; + exclusiveBind = exclBind; } void socketCreate(boolean stream) throws IOException { @@ -90,7 +100,7 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl if (address == null) throw new NullPointerException("inet address argument is null."); - bind0(nativefd, address, port); + bind0(nativefd, address, port, exclusiveBind); if (port == 0) { localport = localPort0(nativefd); } else { @@ -158,6 +168,8 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl shutdown0(nativefd, howto); } + // Intentional fallthrough after SO_REUSEADDR + @SuppressWarnings("fallthrough") void socketSetOption(int opt, boolean on, Object value) throws SocketException { cli.System.Net.Sockets.Socket nativefd = checkAndReturnNativeFD(); @@ -169,10 +181,16 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl int optionValue = 0; switch(opt) { + case SO_REUSEADDR : + if (exclusiveBind) { + // SO_REUSEADDR emulated when using exclusive bind + isReuseAddress = on; + return; + } + // intentional fallthrough case TCP_NODELAY : case SO_OOBINLINE : case SO_KEEPALIVE : - case SO_REUSEADDR : optionValue = on ? 1 : 0; break; case SO_SNDBUF : @@ -203,6 +221,10 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl return 0; // return value doesn't matter. } + // SO_REUSEADDR emulated when using exclusive bind + if (opt == SO_REUSEADDR && exclusiveBind) + return isReuseAddress? 1 : -1; + int value = getIntOption(nativefd, opt); switch (opt) { @@ -238,10 +260,11 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl return ret; } - static void bind0(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport) + static void bind0(cli.System.Net.Sockets.Socket fd, InetAddress localAddress, int localport, + boolean exclBind) throws IOException { ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); - DualStackPlainSocketImpl_c.bind0(env, fd, localAddress, localport); + DualStackPlainSocketImpl_c.bind0(env, fd, localAddress, localport, exclBind); env.ThrowPendingException(); } diff --git a/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl_c.java b/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl_c.java index b5b856dd23..15c2a1848b 100644 --- a/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl_c.java +++ b/external/ikvm/openjdk/java/net/DualStackPlainSocketImpl_c.java @@ -97,7 +97,9 @@ static cli.System.Net.Sockets.Socket socket0 * Signature: (ILjava/net/InetAddress;I)V */ static void bind0 - (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port) { + (JNIEnv env, cli.System.Net.Sockets.Socket fd, InetAddress iaObj, int port, + boolean exclBind) +{ SOCKETADDRESS sa; sa = new SOCKETADDRESS(); int rv; @@ -107,7 +109,7 @@ static void bind0 return; } - rv = NET_Bind(fd, sa); + rv = NET_WinBind(fd, sa, exclBind); if (rv == SOCKET_ERROR) NET_ThrowNew(env, WSAGetLastError(), "JVM_Bind"); diff --git a/external/ikvm/openjdk/java/net/PlainSocketImpl.java b/external/ikvm/openjdk/java/net/PlainSocketImpl.java index d67825bc61..5b7f850d18 100644 --- a/external/ikvm/openjdk/java/net/PlainSocketImpl.java +++ b/external/ikvm/openjdk/java/net/PlainSocketImpl.java @@ -54,6 +54,12 @@ class PlainSocketImpl extends AbstractPlainSocketImpl /* If the version supports a dual stack TCP implementation */ private static boolean useDualStackImpl = false; + /* sun.net.useExclusiveBind */ + private static String exclBindProp; + + /* True if exclusive binding is on for Windows */ + private static boolean exclusiveBind = true; + static { java.security.AccessController.doPrivileged( new PrivilegedAction<Object>() { public Object run() { @@ -62,6 +68,7 @@ class PlainSocketImpl extends AbstractPlainSocketImpl version = Float.parseFloat(System.getProperties().getProperty("os.version")); preferIPv4Stack = Boolean.parseBoolean( System.getProperties().getProperty("java.net.preferIPv4Stack")); + exclBindProp = System.getProperty("sun.net.useExclusiveBind"); } catch (NumberFormatException e ) { assert false : e; } @@ -84,7 +91,15 @@ class PlainSocketImpl extends AbstractPlainSocketImpl // (version >= 6.0) implies Vista or greater. if (version >= 6.0 && !preferIPv4Stack) { - useDualStackImpl = true; + useDualStackImpl = true; + } + + if (exclBindProp != null) { + // sun.net.useExclusiveBind is true + exclusiveBind = exclBindProp.length() == 0 ? true + : Boolean.parseBoolean(exclBindProp); + } else if (version < 6.0) { + exclusiveBind = false; } } @@ -93,9 +108,9 @@ class PlainSocketImpl extends AbstractPlainSocketImpl */ PlainSocketImpl() { if (useDualStackImpl) { - impl = new DualStackPlainSocketImpl(); + impl = new DualStackPlainSocketImpl(exclusiveBind); } else { - impl = new TwoStacksPlainSocketImpl(); + impl = new TwoStacksPlainSocketImpl(exclusiveBind); } } @@ -104,9 +119,9 @@ class PlainSocketImpl extends AbstractPlainSocketImpl */ PlainSocketImpl(FileDescriptor fd) { if (useDualStackImpl) { - impl = new DualStackPlainSocketImpl(fd); + impl = new DualStackPlainSocketImpl(fd, exclusiveBind); } else { - impl = new TwoStacksPlainSocketImpl(fd); + impl = new TwoStacksPlainSocketImpl(fd, exclusiveBind); } } diff --git a/external/ikvm/openjdk/java/net/SocketInputStream.java b/external/ikvm/openjdk/java/net/SocketInputStream.java index 830fa51ce1..161947cc5e 100644 --- a/external/ikvm/openjdk/java/net/SocketInputStream.java +++ b/external/ikvm/openjdk/java/net/SocketInputStream.java @@ -32,6 +32,7 @@ import java.nio.channels.FileChannel; import static ikvm.internal.Winsock.*; import static java.net.net_util_md.*; +import sun.misc.IoTrace; import sun.net.ConnectionResetException; /** @@ -41,7 +42,6 @@ import sun.net.ConnectionResetException; * * @author Jonathan Payne * @author Arthur van Hoff - * @author Jeroen Frijters */ class SocketInputStream extends FileInputStream { @@ -182,7 +182,7 @@ class SocketInputStream extends FileInputStream } int read(byte b[], int off, int length, int timeout) throws IOException { - int n; + int n = 0; // EOF already encountered if (eof) { @@ -204,6 +204,7 @@ class SocketInputStream extends FileInputStream boolean gotReset = false; + Object traceContext = IoTrace.socketReadBegin(); // acquire file descriptor and do the read FileDescriptor fd = impl.acquireFD(); try { @@ -215,6 +216,8 @@ class SocketInputStream extends FileInputStream gotReset = true; } finally { impl.releaseFD(); + IoTrace.socketReadEnd(traceContext, impl.address, impl.port, + timeout, n > 0 ? n : 0); } /* @@ -222,6 +225,7 @@ class SocketInputStream extends FileInputStream * buffered on the socket */ if (gotReset) { + traceContext = IoTrace.socketReadBegin(); impl.setConnectionResetPending(); impl.acquireFD(); try { @@ -232,6 +236,8 @@ class SocketInputStream extends FileInputStream } catch (ConnectionResetException rstExc) { } finally { impl.releaseFD(); + IoTrace.socketReadEnd(traceContext, impl.address, impl.port, + timeout, n > 0 ? n : 0); } } diff --git a/external/ikvm/openjdk/java/net/SocketOutputStream.java b/external/ikvm/openjdk/java/net/SocketOutputStream.java index 9e6be018d9..fd6e2c4fb9 100644 --- a/external/ikvm/openjdk/java/net/SocketOutputStream.java +++ b/external/ikvm/openjdk/java/net/SocketOutputStream.java @@ -32,6 +32,8 @@ import java.nio.channels.FileChannel; import static ikvm.internal.Winsock.*; import static java.net.net_util_md.*; +import sun.misc.IoTrace; + /** * This stream extends FileOutputStream to implement a * SocketOutputStream. Note that this class should <b>NOT</b> be @@ -39,7 +41,6 @@ import static java.net.net_util_md.*; * * @author Jonathan Payne * @author Arthur van Hoff - * @author Jeroen Frijters */ class SocketOutputStream extends FileOutputStream { @@ -176,9 +177,12 @@ class SocketOutputStream extends FileOutputStream throw new ArrayIndexOutOfBoundsException(); } + Object traceContext = IoTrace.socketWriteBegin(); + int bytesWritten = 0; FileDescriptor fd = impl.acquireFD(); try { socketWrite0(fd, b, off, len); + bytesWritten = len; } catch (SocketException se) { if (se instanceof sun.net.ConnectionResetException) { impl.setConnectionResetPending(); @@ -191,6 +195,7 @@ class SocketOutputStream extends FileOutputStream } } finally { impl.releaseFD(); + IoTrace.socketWriteEnd(traceContext, impl.address, impl.port, bytesWritten); } } diff --git a/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java b/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java index a119c4b7fe..2b2bde1b41 100644 --- a/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java +++ b/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl.java @@ -38,7 +38,6 @@ import sun.net.ResourceManager; * during socket creation. * * @author Chris Hegarty - * @author Jeroen Frijters */ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl @@ -63,6 +62,22 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl */ cli.System.Net.Sockets.Socket lastfd=null; + // true if this socket is exclusively bound + private final boolean exclusiveBind; + + /* + * Set to true if SO_REUSEADDR is set after the socket is bound to + * indicate SO_REUSEADDR is being emulated + */ + private boolean reuseAddressEmulated; + + // emulates SO_REUSEADDR when exclusiveBind is true and socket is bound + private boolean isReuseAddress; + + TwoStacksPlainDatagramSocketImpl(boolean exclBind) { + exclusiveBind = exclBind; + } + protected synchronized void create() throws SocketException { fd1 = new FileDescriptor(); try { @@ -81,6 +96,14 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl } } + @Override + protected synchronized void bind0(int lport, InetAddress laddr) + throws SocketException + { + bind0(lport, laddr, exclusiveBind); + + } + protected synchronized void receive(DatagramPacket p) throws IOException { try { @@ -100,8 +123,24 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl return anyLocalBoundAddr; } return socketGetOption(optID); - } else + } else if (optID == SO_REUSEADDR && reuseAddressEmulated) { + return isReuseAddress; + } else { return super.getOption(optID); + } + } + + protected void socketSetOption(int opt, Object val) + throws SocketException + { + if (opt == SO_REUSEADDR && exclusiveBind && localPort != 0) { + // socket already bound, emulate + reuseAddressEmulated = true; + isReuseAddress = (Boolean)val; + } else { + socketNativeSetOption(opt, val); + } + } protected boolean isClosed() { @@ -119,9 +158,10 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl /* Native methods */ - protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException { + protected synchronized void bind0(int lport, InetAddress laddr, + boolean exclBind) throws SocketException { ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); - TwoStacksPlainDatagramSocketImpl_c.bind0(env, this, lport, laddr); + TwoStacksPlainDatagramSocketImpl_c.bind0(env, this, lport, laddr, exclBind); env.ThrowPendingException(); } @@ -199,9 +239,9 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl TwoStacksPlainDatagramSocketImpl_c.datagramSocketClose(this); } - protected void socketSetOption(int opt, Object val) throws SocketException { + protected void socketNativeSetOption(int opt, Object val) throws SocketException { ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); - TwoStacksPlainDatagramSocketImpl_c.socketSetOption(env, this, opt, val); + TwoStacksPlainDatagramSocketImpl_c.socketNativeSetOption(env, this, opt, val); env.ThrowPendingException(); } diff --git a/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java b/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java index 8f7e1644d3..26f78adc32 100644 --- a/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java +++ b/external/ikvm/openjdk/java/net/TwoStacksPlainDatagramSocketImpl_c.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -282,7 +282,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size) addrList = curr; } LeaveCriticalSection(&sizeCheckLock); - JNU_ThrowOutOfMemoryError(env, "heap allocation failed"); + JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); return JNI_TRUE; } curr->addr = htonl((*addrp)->S_un.S_addr); @@ -447,7 +447,9 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) { } */ -static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int port, InetAddress addressObj) { +static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, + int port, InetAddress addressObj, + boolean exclBind) { FileDescriptor fdObj = _this.fd; FileDescriptor fd1Obj = _this.fd1; @@ -459,12 +461,7 @@ static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int port, SOCKETADDRESS lcladdr; lcladdr = new SOCKETADDRESS(); - if (IS_NULL(addressObj)) { - JNU_ThrowNullPointerException(env, "argument address"); - return; - } - - family = addressObj.family; + family = getInetAddress_family(env, addressObj); if (family == IPv6 && !ipv6_supported) { JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Protocol family not supported"); @@ -494,7 +491,7 @@ static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int port, v6bind.addr = lcladdr; v6bind.ipv4_fd = fd; v6bind.ipv6_fd = fd1; - if (NET_BindV6(v6bind) != -1) { + if (NET_BindV6(v6bind, exclBind) != -1) { /* check if the fds have changed */ if (v6bind.ipv4_fd != fd) { fd = v6bind.ipv4_fd; @@ -521,7 +518,7 @@ static void bind0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int port, return; } } else { - if (bind(fd, lcladdr) == -1) { + if (NET_WinBind(fd, lcladdr, exclBind) == -1) { if (WSAGetLastError() == WSAEACCES) { WSASetLastError(WSAEADDRINUSE); } @@ -582,9 +579,9 @@ static void connect0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAdd return; } - addr = address.address; + addr = getInetAddress_addr(env, address); - family = address.family; + family = getInetAddress_family(env, address); if (family == IPv6 && !ipv6_supported) { JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", "Protocol family not supported"); @@ -686,7 +683,7 @@ static void send(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPac return; } - family = iaObj.family; + family = getInetAddress_family(env, iaObj); if (family == IPv4) { fdObj = _this.fd; } else { @@ -730,7 +727,7 @@ static void send(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPac if (!w2k_or_later) { /* avoid this check on Win 2K or better. Does not work with IPv6. * Check is not necessary on these OSes *-/ if (connected) { - address = (*env)->GetIntField(env, iaObj, ia_addressID); + address = getInetAddress_addr(env, iaObj); } else { address = ntohl(rmtaddr.him4.sin_addr.s_addr); } @@ -756,7 +753,7 @@ static void send(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, DatagramPac *-/ fullPacket = (char *)malloc(packetBufferLen); if (!fullPacket) { - JNU_ThrowOutOfMemoryError(env, "heap allocation failed"); + JNU_ThrowOutOfMemoryError(env, "Send buf native heap allocation failed"); return; } } else { @@ -830,7 +827,7 @@ static int peek(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, InetAddress JNU_ThrowNullPointerException(env, "Null address in peek()"); return -1; } else { - address = addressObj.address; + address = getInetAddress_addr(env, addressObj); /* We only handle IPv4 for now. Will support IPv6 once its in the os */ family = AF_INET; } @@ -1009,7 +1006,7 @@ static int peekData(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, Datagram *-/ fullPacket = (char *)malloc(packetBufferLen); if (!fullPacket) { - JNU_ThrowOutOfMemoryError(env, "heap allocation failed"); + JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); return -1; } } else { @@ -1275,7 +1272,7 @@ static void receive0(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, Datagra *-/ fullPacket = (char *)malloc(packetBufferLen); if (!fullPacket) { - JNU_ThrowOutOfMemoryError(env, "heap allocation failed"); + JNU_ThrowOutOfMemoryError(env, "Receive buf native heap allocation failed"); return; } } else { @@ -1549,7 +1546,7 @@ private static int getInetAddrFromIf (JNIEnv env, int family, NetworkInterface n for (i=0; i<len; i++) { int fam; addr = addrArray[i]; - fam = addr.family; + fam = getInetAddress_family(env, addr); if (fam == family) { iaddr[0] = addr; return 0; @@ -1567,7 +1564,7 @@ private static int getInet4AddrFromIf (JNIEnv env, NetworkInterface nif, in_addr return -1; } - iaddr.s_addr = htonl(addr[0].address); + iaddr.s_addr = htonl(getInetAddress_addr(env, addr[0])); return 0; } @@ -1660,7 +1657,7 @@ private static void setMulticastInterface(JNIEnv env, TwoStacksPlainDatagramSock } else { in_addr in = new in_addr(); - in.s_addr = htonl(((InetAddress)value).address); + in.s_addr = htonl(getInetAddress_addr(env, (InetAddress)value)); if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, in) < 0) { @@ -1734,10 +1731,10 @@ private static void setMulticastInterface(JNIEnv env, TwoStacksPlainDatagramSock /* * Class: java_net_TwoStacksPlainDatagramSocketImpl - * Method: socketSetOption + * Method: socketNativeSetOption * Signature: (ILjava/lang/Object;)V */ -static void socketSetOption(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int opt, Object value) { +static void socketNativeSetOption(JNIEnv env, TwoStacksPlainDatagramSocketImpl _this, int opt, Object value) { cli.System.Net.Sockets.Socket fd = null; cli.System.Net.Sockets.Socket fd1 = null; int[] levelv4 = new int[1]; diff --git a/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl.java b/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl.java index 4179078852..12c1794f7d 100644 --- a/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl.java +++ b/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl.java @@ -66,10 +66,20 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl */ cli.System.Net.Sockets.Socket lastfd = null; - public TwoStacksPlainSocketImpl() {} + // true if this socket is exclusively bound + private final boolean exclusiveBind; - public TwoStacksPlainSocketImpl(FileDescriptor fd) { + // emulates SO_REUSEADDR when exclusiveBind is true + private boolean isReuseAddress; + + + public TwoStacksPlainSocketImpl(boolean exclBind) { + exclusiveBind = exclBind; + } + + public TwoStacksPlainSocketImpl(FileDescriptor fd, boolean exclBind) { this.fd = fd; + exclusiveBind = exclBind; } /** @@ -112,13 +122,33 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl InetAddressContainer in = new InetAddressContainer(); socketGetOption(opt, in); return in.addr; + } else if (opt == SO_REUSEADDR && exclusiveBind) { + // SO_REUSEADDR emulated when using exclusive bind + return isReuseAddress; } else return super.getOption(opt); } + @Override + void socketBind(InetAddress address, int port) throws IOException { + socketBind(address, port, exclusiveBind); + } + + @Override + void socketSetOption(int opt, boolean on, Object value) + throws SocketException + { + // SO_REUSEADDR emulated when using exclusive bind + if (opt == SO_REUSEADDR && exclusiveBind) + isReuseAddress = on; + else + socketNativeSetOption(opt, on, value); + } + /** * Closes the socket. */ + @Override protected void close() throws IOException { synchronized(fdLock) { if (fd != null || fd1 != null) { @@ -151,6 +181,7 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl } } + @Override void reset() throws IOException { if (fd != null || fd1 != null) { socketClose(); @@ -163,6 +194,7 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl /* * Return true if already closed or close is pending */ + @Override public boolean isClosedOrPending() { /* * Lock on fdLock to ensure that we wait if a @@ -191,9 +223,9 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl env.ThrowPendingException(); } - void socketBind(InetAddress address, int localport) throws IOException { + void socketBind(InetAddress address, int localport, boolean exclBind) throws IOException { ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); - TwoStacksPlainSocketImpl_c.socketBind(env, this, address, localport); + TwoStacksPlainSocketImpl_c.socketBind(env, this, address, localport, exclBind); env.ThrowPendingException(); } @@ -228,9 +260,9 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl env.ThrowPendingException(); } - void socketSetOption(int cmd, boolean on, Object value) throws SocketException { + void socketNativeSetOption(int cmd, boolean on, Object value) throws SocketException { ikvm.internal.JNI.JNIEnv env = new ikvm.internal.JNI.JNIEnv(); - TwoStacksPlainSocketImpl_c.socketSetOption(env, this, cmd, on, value); + TwoStacksPlainSocketImpl_c.socketNativeSetOption(env, this, cmd, on, value); env.ThrowPendingException(); } diff --git a/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl_c.java b/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl_c.java index f6296bd4dd..d86e84d07e 100644 --- a/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl_c.java +++ b/external/ikvm/openjdk/java/net/TwoStacksPlainSocketImpl_c.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -416,7 +416,9 @@ static void socketConnect(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddres * Method: socketBind * Signature: (Ljava/net/InetAddress;I)V */ -static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddress iaObj, int localport) { +static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this, + InetAddress iaObj, int localport, + boolean exclBind) { FileDescriptor fdObj = _this.fd; FileDescriptor fd1Obj = _this.fd1; cli.System.Net.Sockets.Socket fd = null; @@ -430,7 +432,7 @@ static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddress i SOCKETADDRESS him; him = new SOCKETADDRESS(); - family = iaObj.family; + family = getInetAddress_family(env, iaObj); if (family == IPv6 && !ipv6_supported) { JNU_ThrowByName(env, JNU_JAVANETPKG+"SocketException", @@ -457,13 +459,12 @@ static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddress i him, JNI_FALSE) != 0) { return; } - if (ipv6_supported) { ipv6bind v6bind = new ipv6bind(); v6bind.addr = him; v6bind.ipv4_fd = fd; v6bind.ipv6_fd = fd1; - rv = NET_BindV6(v6bind); + rv = NET_BindV6(v6bind, exclBind); if (rv != -1) { /* check if the fds have changed */ if (v6bind.ipv4_fd != fd) { @@ -488,7 +489,7 @@ static void socketBind(JNIEnv env, TwoStacksPlainSocketImpl _this, InetAddress i } } } else { - rv = NET_Bind(fd, him); + rv = NET_WinBind(fd, him, exclBind); } if (rv == -1) { @@ -787,10 +788,10 @@ static void socketClose0(JNIEnv env, TwoStacksPlainSocketImpl _this, boolean use * * * Class: java_net_TwoStacksPlainSocketImpl - * Method: socketSetOption + * Method: socketNativeSetOption * Signature: (IZLjava/lang/Object;)V */ -static void socketSetOption(JNIEnv env, TwoStacksPlainSocketImpl _this, int cmd, boolean on, Object value) { +static void socketNativeSetOption(JNIEnv env, TwoStacksPlainSocketImpl _this, int cmd, boolean on, Object value) { cli.System.Net.Sockets.Socket fd, fd1; int[] level = new int[1]; int[] optname = new int[1]; diff --git a/external/ikvm/openjdk/java/net/net_util_md.java b/external/ikvm/openjdk/java/net/net_util_md.java index d91323596b..724ba4ccf7 100644 --- a/external/ikvm/openjdk/java/net/net_util_md.java +++ b/external/ikvm/openjdk/java/net/net_util_md.java @@ -271,6 +271,17 @@ final class net_util_md optval = tos; } + if (optname == SO_REUSEADDR) { + /* + * Do not set SO_REUSEADDE if SO_EXCLUSIVEADDUSE is already set + */ + int[] parg = new int[1]; + rv = NET_GetSockOpt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, parg); + if (rv == 0 && parg[0] == 1) { + return rv; + } + } + rv = setsockopt(s, level, optname, optval); if (rv == SOCKET_ERROR) { @@ -330,6 +341,18 @@ final class net_util_md } /* + * Sets SO_ECLUSIVEADDRUSE if SO_REUSEADDR is not already set. + */ + static void setExclusiveBind(cli.System.Net.Sockets.Socket fd) { + int[] parg = new int[1]; + int rv = 0; + rv = NET_GetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, parg); + if (rv == 0 && parg[0] == 0) { + rv = NET_SetSockOpt(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1); + } + } + + /* * Wrapper for bind winsock call - transparent converts an * error related to binding to a port that has exclusive access * into an error indicating the port is in use (facilitates @@ -337,7 +360,8 @@ final class net_util_md */ static int NET_Bind(cli.System.Net.Sockets.Socket s, SOCKETADDRESS him) { - int rv = bind(s, him); + int rv; + rv = bind(s, him); if (rv == SOCKET_ERROR) { /* @@ -352,6 +376,17 @@ final class net_util_md return rv; } + /* + * Wrapper for NET_Bind call. Sets SO_EXCLUSIVEADDRUSE + * if required, and then calls NET_BIND + */ + static int NET_WinBind(cli.System.Net.Sockets.Socket s, SOCKETADDRESS him, boolean exclBind) + { + if (exclBind == JNI_TRUE) + setExclusiveBind(s); + return NET_Bind(s, him); + } + static int NET_SocketClose(cli.System.Net.Sockets.Socket fd) { linger l = new linger(); int ret; @@ -470,7 +505,7 @@ final class net_util_md return SOCKET_ERROR; } - static int NET_BindV6(ipv6bind b) { + static int NET_BindV6(ipv6bind b, boolean exclBind) { cli.System.Net.Sockets.Socket fd = null; cli.System.Net.Sockets.Socket ofd = null; int rv; @@ -487,7 +522,7 @@ final class net_util_md if (family == AF_INET && (b.addr.him4.sin_addr.s_addr != INADDR_ANY)) { /* bind to v4 only */ int ret; - ret = NET_Bind (b.ipv4_fd, b.addr); + ret = NET_WinBind (b.ipv4_fd, b.addr, exclBind); if (ret == SOCKET_ERROR) { return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b); } @@ -498,7 +533,7 @@ final class net_util_md if (family == AF_INET6 && (!IN6ADDR_ISANY(b.addr))) { /* bind to v6 only */ int ret; - ret = NET_Bind (b.ipv6_fd, b.addr); + ret = NET_WinBind (b.ipv6_fd, b.addr, exclBind); if (ret == SOCKET_ERROR) { return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b); } @@ -523,7 +558,7 @@ final class net_util_md oaddr.set(new IPEndPoint(IPAddress.Any, htons(port))); } - rv = NET_Bind (fd, b.addr); + rv = NET_WinBind (fd, b.addr, exclBind); if (rv == SOCKET_ERROR) { return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b); } @@ -568,7 +603,8 @@ final class net_util_md /* bind random port on first socket */ oaddr.sin_port = 0; - rv = NET_Bind (ofd, oaddr); + rv = NET_WinBind (ofd, oaddr, + exclBind); if (rv == SOCKET_ERROR) { return CLOSE_SOCKETS_AND_RETURN(fd, ofd, close_fd, close_ofd, b); } @@ -583,7 +619,8 @@ final class net_util_md } bound_port = oaddr.sin_port; b.addr.sin_port = bound_port; - rv = NET_Bind (fd, b.addr); + rv = NET_WinBind (fd, b.addr, + exclBind); if (rv != SOCKET_ERROR) { if (family == AF_INET) { @@ -836,4 +873,12 @@ final class net_util_md } return sock; } + + static int getInetAddress_addr(JNIEnv env, InetAddress iaObj) { + return iaObj.address; + } + + static int getInetAddress_family(JNIEnv env, InetAddress iaObj) { + return iaObj.family; + } } diff --git a/external/ikvm/openjdk/java/security/AccessController.java b/external/ikvm/openjdk/java/security/AccessController.java index 60b7722a3b..19d4af9603 100644 --- a/external/ikvm/openjdk/java/security/AccessController.java +++ b/external/ikvm/openjdk/java/security/AccessController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ package java.security; import ikvm.internal.CallerID; import sun.misc.Unsafe; import sun.security.util.Debug; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; /** * <p> The AccessController class is used for access control operations @@ -317,7 +319,7 @@ public final class AccessController { * @see java.security.DomainCombiner */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedAction<T> action) { return (T)doPrivileged(action, null, CallerID.getCallerID()); } @@ -344,14 +346,14 @@ public final class AccessController { * * @since 1.6 */ + @CallerSensitive public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { - - DomainCombiner dc = null; AccessControlContext acc = getStackAccessControlContext(); - if (acc == null || (dc = acc.getAssignedCombiner()) == null) { + if (acc == null) { return AccessController.doPrivileged(action); } - return AccessController.doPrivileged(action, preserveCombiner(dc)); + DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc, Reflection.getCallerClass())); } @@ -382,7 +384,7 @@ public final class AccessController { * @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedAction<T> action, AccessControlContext context) { return (T)doPrivileged(action, context, CallerID.getCallerID()); @@ -412,7 +414,7 @@ public final class AccessController { * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction) * @see java.security.DomainCombiner */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws PrivilegedActionException { @@ -445,41 +447,39 @@ public final class AccessController { * * @since 1.6 */ + @CallerSensitive public static <T> T doPrivilegedWithCombiner (PrivilegedExceptionAction<T> action) throws PrivilegedActionException { - DomainCombiner dc = null; AccessControlContext acc = getStackAccessControlContext(); - if (acc == null || (dc = acc.getAssignedCombiner()) == null) { + if (acc == null) { return AccessController.doPrivileged(action); } - return AccessController.doPrivileged(action, preserveCombiner(dc)); + DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc, Reflection.getCallerClass())); } /** * preserve the combiner across the doPrivileged call */ - private static AccessControlContext preserveCombiner - (DomainCombiner combiner) { - - /** - * callerClass[0] = Reflection.getCallerClass - * callerClass[1] = AccessController.preserveCombiner - * callerClass[2] = AccessController.doPrivileged - * callerClass[3] = caller - */ - final Class callerClass = sun.reflect.Reflection.getCallerClass(3); + private static AccessControlContext preserveCombiner(DomainCombiner combiner, + final Class<?> caller) { ProtectionDomain callerPd = doPrivileged (new PrivilegedAction<ProtectionDomain>() { public ProtectionDomain run() { - return callerClass.getProtectionDomain(); + return caller.getProtectionDomain(); } }); // perform 'combine' on the caller of doPrivileged, // even if the caller is from the bootclasspath ProtectionDomain[] pds = new ProtectionDomain[] {callerPd}; - return new AccessControlContext(combiner.combine(pds, null), combiner); + if (combiner == null) { + return new AccessControlContext(pds); + } else { + return new AccessControlContext(combiner.combine(pds, null), + combiner); + } } @@ -512,7 +512,7 @@ public final class AccessController { * @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static <T> T doPrivileged(PrivilegedExceptionAction<T> action, AccessControlContext context) diff --git a/external/ikvm/openjdk/java/sql/DriverManager.java b/external/ikvm/openjdk/java/sql/DriverManager.java index 9e357f4669..8698345c17 100644 --- a/external/ikvm/openjdk/java/sql/DriverManager.java +++ b/external/ikvm/openjdk/java/sql/DriverManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,13 @@ package java.sql; -import ikvm.internal.CallerID; import java.util.Iterator; -import java.sql.Driver; import java.util.ServiceLoader; import java.security.AccessController; import java.security.PrivilegedAction; - +import java.util.concurrent.CopyOnWriteArrayList; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; /** * <P>The basic service for managing a set of JDBC drivers.<br> @@ -80,6 +80,27 @@ import java.security.PrivilegedAction; public class DriverManager { + // List of registered JDBC drivers + private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>(); + private static volatile int loginTimeout = 0; + private static volatile java.io.PrintWriter logWriter = null; + private static volatile java.io.PrintStream logStream = null; + // Used in println() to synchronize logWriter + private final static Object logSync = new Object(); + + /* Prevent the DriverManager class from being instantiated. */ + private DriverManager(){} + + + /** + * Load the initial JDBC drivers by checking the System property + * jdbc.properties and then use the {@code ServiceLoader} mechanism + */ + static { + loadInitialDrivers(); + println("JDBC DriverManager initialized"); + } + /** * The <code>SQLPermission</code> constant that allows the * setting of the logging stream. @@ -160,15 +181,10 @@ public class DriverManager { * @return a Connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url, java.util.Properties info) throws SQLException { - - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -184,15 +200,11 @@ public class DriverManager { * @return a connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url, String user, String password) throws SQLException { java.util.Properties info = new java.util.Properties(); - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - if (user != null) { info.put("user", user); } @@ -200,7 +212,7 @@ public class DriverManager { info.put("password", password); } - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -213,17 +225,12 @@ public class DriverManager { * @return a connection to the URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Connection getConnection(String url) throws SQLException { java.util.Properties info = new java.util.Properties(); - - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - - return (getConnection(url, info, callerCL)); + return (getConnection(url, info, Reflection.getCallerClass())); } /** @@ -237,47 +244,34 @@ public class DriverManager { * that can connect to the given URL * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static Driver getDriver(String url) throws SQLException { - java.util.Vector drivers = null; println("DriverManager.getDriver(\"" + url + "\")"); - if (!initialized) { - initialize(); - } + Class<?> callerClass = Reflection.getCallerClass(); - synchronized (DriverManager.class){ - // use the read copy of the drivers vector - drivers = readDrivers; - } - - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); - - // Walk through the loaded drivers attempting to locate someone + // Walk through the loaded registeredDrivers attempting to locate someone // who understands the given URL. - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + for (DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != - di.driverClass ) { - println(" skipping: " + di); - continue; - } - try { - println(" trying " + di); - if (di.driver.acceptsURL(url)) { - // Success! - println("getDriver returning " + di); - return (di.driver); + if(isDriverAllowed(aDriver.driver, callerClass)) { + try { + if(aDriver.driver.acceptsURL(url)) { + // Success! + println("getDriver returning " + aDriver.driver.getClass().getName()); + return (aDriver.driver); + } + + } catch(SQLException sqe) { + // Drop through and try the next driver. } - } catch (SQLException ex) { - // Drop through and try the next driver. + } else { + println(" skipping: " + aDriver.driver.getClass().getName()); } + } println("getDriver: no suitable driver"); @@ -297,23 +291,16 @@ public class DriverManager { */ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { - if (!initialized) { - initialize(); - } - - DriverInfo di = new DriverInfo(); - di.driver = driver; - di.driverClass = driver.getClass(); - di.driverClassName = di.driverClass.getName(); - - // Not Required -- drivers.addElement(di); - - writeDrivers.addElement(di); - println("registerDriver: " + di); + /* Register the driver if it has not already been added to our list */ + if(driver != null) { + registeredDrivers.addIfAbsent(new DriverInfo(driver)); + } else { + // This is for compatibility with the original DriverManager + throw new NullPointerException(); + } - /* update the read copy of drivers vector */ - readDrivers = (java.util.Vector) writeDrivers.clone(); + println("registerDriver: " + driver); } @@ -324,40 +311,27 @@ public class DriverManager { * @param driver the JDBC Driver to drop * @exception SQLException if a database access error occurs */ - @ikvm.internal.HasCallerID + @CallerSensitive public static synchronized void deregisterDriver(Driver driver) throws SQLException { - // Gets the classloader of the code that called this method, - // may be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); + if (driver == null) { + return; + } + println("DriverManager.deregisterDriver: " + driver); - // Walk through the loaded drivers. - int i; - DriverInfo di = null; - for (i = 0; i < writeDrivers.size(); i++) { - di = (DriverInfo)writeDrivers.elementAt(i); - if (di.driver == driver) { - break; + DriverInfo aDriver = new DriverInfo(driver); + if(registeredDrivers.contains(aDriver)) { + if (isDriverAllowed(driver, Reflection.getCallerClass())) { + registeredDrivers.remove(aDriver); + } else { + // If the caller does not have permission to load the driver then + // throw a SecurityException. + throw new SecurityException(); } - } - // If we can't find the driver just return. - if (i >= writeDrivers.size()) { + } else { println(" couldn't find driver to unload"); - return; - } - - // If the caller does not have permission to load the driver then - // throw a security exception. - if (getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - throw new SecurityException(); } - - // Remove the driver. Other entries in drivers get shuffled down. - writeDrivers.removeElementAt(i); - - /* update the read copy of drivers vector */ - readDrivers = (java.util.Vector) writeDrivers.clone(); } /** @@ -369,36 +343,22 @@ public class DriverManager { * * @return the list of JDBC Drivers loaded by the caller's class loader */ - @ikvm.internal.HasCallerID + @CallerSensitive public static java.util.Enumeration<Driver> getDrivers() { java.util.Vector<Driver> result = new java.util.Vector<Driver>(); - java.util.Vector drivers = null; - - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the readcopy of drivers - drivers = readDrivers; - } - // Gets the classloader of the code that called this method, may - // be null. - ClassLoader callerCL = CallerID.getCallerID().getCallerClassLoader(); + Class<?> callerClass = Reflection.getCallerClass(); - // Walk through the loaded drivers. - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + // Walk through the loaded registeredDrivers. + for(DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - println(" skipping: " + di); - continue; + if(isDriverAllowed(aDriver.driver, callerClass)) { + result.addElement(aDriver.driver); + } else { + println(" skipping: " + aDriver.getClass().getName()); } - result.addElement(di.driver); } - return (result.elements()); } @@ -488,28 +448,34 @@ public class DriverManager { //------------------------------------------------------------------------ - // Returns the class object that would be created if the code calling the - // driver manager had loaded the driver class, or null if the class - // is inaccessible. - private static Class getCallerClass(ClassLoader callerClassLoader, - String driverClassName) { - Class callerC = null; + // Indicates whether the class object that would be created if the code calling + // DriverManager is accessible. + private static boolean isDriverAllowed(Driver driver, Class<?> caller) { + ClassLoader callerCL = caller != null ? caller.getClassLoader() : null; + return isDriverAllowed(driver, callerCL); + } - try { - callerC = Class.forName(driverClassName, true, callerClassLoader); - } - catch (Exception ex) { - callerC = null; // being very careful + private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) { + boolean result = false; + if(driver != null) { + Class<?> aClass = null; + try { + aClass = Class.forName(driver.getClass().getName(), true, classLoader); + } catch (Exception ex) { + result = false; + } + + result = ( aClass == driver.getClass() ) ? true : false; } - return callerC; + return result; } private static void loadInitialDrivers() { String drivers; try { - drivers = (String) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + drivers = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { return System.getProperty("jdbc.drivers"); } }); @@ -521,8 +487,8 @@ public class DriverManager { // exposed as a java.sql.Driver.class service. // ServiceLoader.load() replaces the sun.misc.Providers() - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction<Void>() { + public Void run() { ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); Iterator driversIterator = loadedDrivers.iterator(); @@ -541,7 +507,7 @@ public class DriverManager { */ try{ while(driversIterator.hasNext()) { - println(" Loading done by the java.util.ServiceLoader : "+driversIterator.next()); + driversIterator.next(); } } catch(Throwable t) { // Do nothing @@ -551,26 +517,17 @@ public class DriverManager { }); println("DriverManager.initialize: jdbc.drivers = " + drivers); - if (drivers == null) { + + if (drivers == null || drivers.equals("")) { return; } - while (drivers.length() != 0) { - int x = drivers.indexOf(':'); - String driver; - if (x < 0) { - driver = drivers; - drivers = ""; - } else { - driver = drivers.substring(0, x); - drivers = drivers.substring(x+1); - } - if (driver.length() == 0) { - continue; - } + String[] driversList = drivers.split(":"); + println("number of Drivers:" + driversList.length); + for (String aDriver : driversList) { try { - println("DriverManager.Initialize: loading " + driver); - Class.forName(driver, true, - ClassLoader.getSystemClassLoader()); + println("DriverManager.Initialize: loading " + aDriver); + Class.forName(aDriver, true, + ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println("DriverManager.Initialize: load failed: " + ex); } @@ -580,19 +537,19 @@ public class DriverManager { // Worker method called by the public getConnection() methods. private static Connection getConnection( - String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { - java.util.Vector drivers = null; + String url, java.util.Properties info, Class<?> caller) throws SQLException { /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) * classloader, so that the JDBC driver class outside rt.jar * can be loaded from here. */ - synchronized(DriverManager.class) { - // synchronize loading of the correct classloader. - if(callerCL == null) { - callerCL = Thread.currentThread().getContextClassLoader(); - } + ClassLoader callerCL = caller != null ? caller.getClassLoader() : null; + synchronized (DriverManager.class) { + // synchronize loading of the correct classloader. + if (callerCL == null) { + callerCL = Thread.currentThread().getContextClassLoader(); + } } if(url == null) { @@ -601,40 +558,32 @@ public class DriverManager { println("DriverManager.getConnection(\"" + url + "\")"); - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the readcopy of drivers - drivers = readDrivers; - } - - // Walk through the loaded drivers attempting to make a connection. + // Walk through the loaded registeredDrivers attempting to make a connection. // Remember the first exception that gets raised so we can reraise it. SQLException reason = null; - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); + for(DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. - if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { - println(" skipping: " + di); - continue; - } - try { - println(" trying " + di); - Connection result = di.driver.connect(url, info); - if (result != null) { - // Success! - println("getConnection returning " + di); - return (result); - } - } catch (SQLException ex) { - if (reason == null) { - reason = ex; + if(isDriverAllowed(aDriver.driver, callerCL)) { + try { + println(" trying " + aDriver.driver.getClass().getName()); + Connection con = aDriver.driver.connect(url, info); + if (con != null) { + // Success! + println("getConnection returning " + aDriver.driver.getClass().getName()); + return (con); + } + } catch (SQLException ex) { + if (reason == null) { + reason = ex; + } } + + } else { + println(" skipping: " + aDriver.getClass().getName()); } + } // if we got here nobody could connect. @@ -646,43 +595,30 @@ public class DriverManager { println("getConnection: no suitable driver found for "+ url); throw new SQLException("No suitable driver found for "+ url, "08001"); } +} +/* + * Wrapper class for registered Drivers in order to not expose Driver.equals() + * to avoid the capture of the Driver it being compared to as it might not + * normally have access. + */ +class DriverInfo { - // Class initialization. - static void initialize() { - if (initialized) { - return; - } - initialized = true; - loadInitialDrivers(); - println("JDBC DriverManager initialized"); + final Driver driver; + DriverInfo(Driver driver) { + this.driver = driver; } - /* Prevent the DriverManager class from being instantiated. */ - private DriverManager(){} - - /* write copy of the drivers vector */ - private static java.util.Vector writeDrivers = new java.util.Vector(); - - /* write copy of the drivers vector */ - private static java.util.Vector readDrivers = new java.util.Vector(); - - private static int loginTimeout = 0; - private static java.io.PrintWriter logWriter = null; - private static java.io.PrintStream logStream = null; - private static boolean initialized = false; - - private static Object logSync = new Object(); - -} + public boolean equals(Object other) { + return (other instanceof DriverInfo) + && this.driver == ((DriverInfo) other).driver; + } -// DriverInfo is a package-private support class. -class DriverInfo { - Driver driver; - Class driverClass; - String driverClassName; + public int hashCode() { + return driver.hashCode(); + } public String toString() { - return ("driver[className=" + driverClassName + "," + driver + "]"); + return ("driver[className=" + driver + "]"); } } diff --git a/external/ikvm/openjdk/java/util/ResourceBundle.java b/external/ikvm/openjdk/java/util/ResourceBundle.java index b572875ec8..98ee3c5195 100644 --- a/external/ikvm/openjdk/java/util/ResourceBundle.java +++ b/external/ikvm/openjdk/java/util/ResourceBundle.java @@ -55,6 +55,8 @@ import java.security.PrivilegedExceptionAction; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.jar.JarEntry; + +import sun.reflect.CallerSensitive; import sun.reflect.Reflection; import sun.util.locale.BaseLocale; import sun.util.locale.LocaleObjectCache; @@ -412,11 +414,10 @@ public abstract class ResourceBundle { /* * Automatic determination of the ClassLoader to be used to load - * resources on behalf of the client. N.B. The client is getLoader's - * caller's caller. + * resources on behalf of the client. */ - private static ClassLoader getLoader(Class c) { - ClassLoader cl = (c == null) ? null : c.getClassLoader(); + private static ClassLoader getLoader(Class<?> caller) { + ClassLoader cl = caller == null ? null : caller.getClassLoader(); if (cl == null) { // When the caller's loader is the boot class loader, cl is null // here. In that case, ClassLoader.getSystemClassLoader() may @@ -714,12 +715,12 @@ public abstract class ResourceBundle { * if no resource bundle for the specified base name can be found * @return a resource bundle for the given base name and the default locale */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName) { return getBundleImpl(baseName, Locale.getDefault(), /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), Control.INSTANCE); } @@ -757,12 +758,12 @@ public abstract class ResourceBundle { * needed. * @since 1.6 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName, Control control) { return getBundleImpl(baseName, Locale.getDefault(), /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), control); } @@ -787,13 +788,13 @@ public abstract class ResourceBundle { * if no resource bundle for the specified base name can be found * @return a resource bundle for the given base name and locale */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName, Locale locale) { return getBundleImpl(baseName, locale, /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), Control.INSTANCE); } @@ -834,12 +835,12 @@ public abstract class ResourceBundle { * needed. * @since 1.6 */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final ResourceBundle getBundle(String baseName, Locale targetLocale, Control control) { return getBundleImpl(baseName, targetLocale, /* must determine loader here, else we break stack invariant */ - getLoader(Reflection.getCallerClass(2)), + getLoader(Reflection.getCallerClass()), control); } @@ -1675,9 +1676,9 @@ public abstract class ResourceBundle { * @since 1.6 * @see ResourceBundle.Control#getTimeToLive(String,Locale) */ - @ikvm.internal.HasCallerID + @CallerSensitive public static final void clearCache() { - clearCache(getLoader(Reflection.getCallerClass(2))); + clearCache(getLoader(Reflection.getCallerClass())); } /** diff --git a/external/ikvm/openjdk/java/util/TimeZone.java b/external/ikvm/openjdk/java/util/TimeZone.java index e3b7cbd54b..63f1028c82 100644 --- a/external/ikvm/openjdk/java/util/TimeZone.java +++ b/external/ikvm/openjdk/java/util/TimeZone.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,8 @@ import java.lang.ref.SoftReference; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.concurrent.ConcurrentHashMap; -import sun.awt.AppContextDC; +import sun.misc.SharedSecrets; +import sun.misc.JavaAWTAccess; import sun.security.action.GetPropertyAction; import sun.util.TimeZoneNameUtility; import sun.util.calendar.ZoneInfo; @@ -718,15 +719,27 @@ abstract public class TimeZone implements Serializable, Cloneable { * Returns the default TimeZone in an AppContext if any AppContext * has ever used. null is returned if any AppContext hasn't been * used or if the AppContext doesn't have the default TimeZone. - */ - private synchronized static TimeZone getDefaultInAppContext() { - if (!hasSetInAppContext) { - return null; - } - - AppContextDC ac = AppContextDC.getAppContext(); - if (ac != null && !ac.isDisposed()) { - return (TimeZone) ac.get(TimeZone.class); + * + * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't + * been loaded. If so, it implies that AWTSecurityManager is not our + * SecurityManager and we can use a local static variable. + * This works around a build time issue. + */ + private static TimeZone getDefaultInAppContext() { + // JavaAWTAccess provides access implementation-private methods without using reflection. + JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess(); + if (javaAWTAccess == null) { + return mainAppContextDefault; + } else { + if (!javaAWTAccess.isDisposed()) { + TimeZone tz = (TimeZone) + javaAWTAccess.get(TimeZone.class); + if (tz == null && javaAWTAccess.isMainAppContext()) { + return mainAppContextDefault; + } else { + return tz; + } + } } return null; } @@ -736,19 +749,23 @@ abstract public class TimeZone implements Serializable, Cloneable { * tz. null is handled special: do nothing if any AppContext * hasn't been used, remove the default TimeZone in the * AppContext otherwise. - */ - private synchronized static void setDefaultInAppContext(TimeZone tz) { - if (!hasSetInAppContext && tz == null) { - return; - } - - AppContextDC ac = AppContextDC.getAppContext(); - if (ac != null && !ac.isDisposed()) { - if (tz != null) { - ac.put(TimeZone.class, tz); - hasSetInAppContext = true; - } else { - ac.remove(TimeZone.class); + * + * Note that javaAWTAccess may be null if sun.awt.AppContext class hasn't + * been loaded. If so, it implies that AWTSecurityManager is not our + * SecurityManager and we can use a local static variable. + * This works around a build time issue. + */ + private static void setDefaultInAppContext(TimeZone tz) { + // JavaAWTAccess provides access implementation-private methods without using reflection. + JavaAWTAccess javaAWTAccess = SharedSecrets.getJavaAWTAccess(); + if (javaAWTAccess == null) { + mainAppContextDefault = tz; + } else { + if (!javaAWTAccess.isDisposed()) { + javaAWTAccess.put(TimeZone.class, tz); + if (javaAWTAccess.isMainAppContext()) { + mainAppContextDefault = null; + } } } } @@ -804,8 +821,8 @@ abstract public class TimeZone implements Serializable, Cloneable { static final String GMT_ID = "GMT"; private static final int GMT_ID_LENGTH = 3; - // true if the default TimeZone has been set in any AppContext - private static boolean hasSetInAppContext; + // a static TimeZone we can reference if no AppContext is in place + private static volatile TimeZone mainAppContextDefault; /** * Parses a custom time zone identifier and returns a corresponding zone. diff --git a/external/ikvm/openjdk/map.xml b/external/ikvm/openjdk/map.xml index 5bc4cd4d4b..33393ac257 100644 --- a/external/ikvm/openjdk/map.xml +++ b/external/ikvm/openjdk/map.xml @@ -228,6 +228,9 @@ <attribute type="IKVM.Attributes.SignatureAttribute" sig="(Ljava.lang.String;)V"> <parameter>Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/lang/CharSequence;</parameter> </attribute> + <attribute type="IKVM.Attributes.NonNestedInnerClassAttribute" sig="(Ljava.lang.String;)V"> + <parameter>java.lang.String$CaseInsensitiveComparator</parameter> + </attribute> <field name="serialVersionUID" sig="J" modifiers="private static final" constant="-6849794470754667710" /> <constructor sig="()V" modifiers="public"> <alternateBody> @@ -895,7 +898,7 @@ <attribute type="System.SerializableAttribute" sig="()V" /> <field name="serialVersionUID" sig="J" modifiers="private static final" constant="-3042686055658047285" /> <field name="serialPersistentFields" sig="[Ljava.io.ObjectStreamField;" modifiers="private static final" /> - <field name="suppressFillInStackTrace" sig="Z" modifiers="private static"> + <field name="suppressFillInStackTrace" sig="Z" modifiers="static"> <attribute type="System.ThreadStaticAttribute" sig="()V" /> </field> <field name="UNASSIGNED_STACK" sig="[Ljava.lang.StackTraceElement;" modifiers="static final" /> @@ -1669,23 +1672,6 @@ </body> </method> </class> - <class name="java.lang.Package"> - <method name="getSystemPackage" sig="(Ljava.lang.String;)Ljava.lang.Package;"> - <body> - <ldsfld class="java.lang.Package" name="pkgs" sig="Ljava.util.Map;" /> - <ldarg_0 /> - <call class="java.lang.LangHelper" name="getSystemPackage" sig="(Ljava.util.Map;Ljava.lang.String;)Ljava.lang.Package;" /> - <ret /> - </body> - </method> - <method name="getSystemPackages" sig="()[Ljava.lang.Package;"> - <body> - <ldsfld class="java.lang.Package" name="pkgs" sig="Ljava.util.Map;" /> - <call class="java.lang.LangHelper" name="getSystemPackages" sig="(Ljava.util.Map;)[Ljava.lang.Package;" /> - <ret /> - </body> - </method> - </class> <!-- This is where the "native" helper methods start --> <class name="ikvm.lang.CIL"> <method name="unbox_byte" sig="(Ljava.lang.Object;)B"> @@ -2732,7 +2718,7 @@ </attribute> <body> <ldarg_0 /> - <call type="IKVM.NativeCode.sun.reflect.Reflection" name="getCallerClass" sig="(I)Ljava.lang.Object;" /> + <call type="Java_sun_reflect_Reflection" name="getCallerClass" sig="(I)Ljava.lang.Object;" /> <stloc name="class" class="java.lang.Object" /> <!-- "leave" is to thwart tail-call optimization --> <leave name="x" /> diff --git a/external/ikvm/openjdk/response.txt b/external/ikvm/openjdk/response.txt index 9dca1438f9..f7d9471db2 100644 --- a/external/ikvm/openjdk/response.txt +++ b/external/ikvm/openjdk/response.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2002-2012 Jeroen Frijters +# Copyright (C) 2002-2013 Jeroen Frijters # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages @@ -27,9 +27,9 @@ assembly.class -baseaddress:0x56000000 -remap:map.xml -exclude:exclude.lst + -resource:META-INF/MANIFEST.MF=MANIFEST.MF -resource:java/lang/uniName.dat=@OPENJDK7@/build/linux-amd64/classes/java/lang/uniName.dat - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/MANIFEST.MF - -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/net/idn/uidna.spp + -resource:sun/net/idn/uidna.spp=@OPENJDK7@/build/linux-amd64/classes/sun/net/idn/uidna.spp ikvm/internal/*.class java/io/*.class java/lang/*.class @@ -42,7 +42,6 @@ assembly.class java/util/*.class java/util/concurrent/locks/*.class gnu/java/util/*.class - sun/awt/AppContextDC.class sun/misc/*.class sun/net/sdp/*.class sun/net/www/protocol/file/*.class @@ -52,6 +51,7 @@ assembly.class sun/nio/cs/*.class sun/nio/fs/*.class sun/reflect/*.class + sun/reflect/misc/*.class ../classpath/gnu/java/net/protocol/ikvmres/*.class ../classpath/ikvm/extensions/*.class ../classpath/ikvm/internal/*.class @@ -428,7 +428,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.Bind.dll - -baseaddress:0x582E0000 + -baseaddress:0x582B0000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/xml/bind/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/bind/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/fastinfoset/* @@ -487,7 +487,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.WebServices.dll - -baseaddress:0x58670000 + -baseaddress:0x58610000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/messaging/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/ws/* @OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/amx/*.class @@ -607,7 +607,7 @@ assembly.class } { -out:IKVM.OpenJDK.XML.Crypto.dll - -baseaddress:0x58BE0000 + -baseaddress:0x58B80000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/security/* @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/*.class @OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/*.class @@ -643,7 +643,7 @@ assembly.class } { -out:IKVM.OpenJDK.SwingAWT.dll - -baseaddress:0x58D30000 + -baseaddress:0x58CD0000 -remap:swingawt.xml -resource:META-INF/services/sun.java2d.pipe.RenderingEngine=resources/META-INF/services/sun.java2d.pipe.RenderingEngine -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/sun.java2d.cmm.PCMM @@ -743,7 +743,7 @@ assembly.class } { -out:IKVM.OpenJDK.Charsets.dll - -baseaddress:0x59F30000 + -baseaddress:0x59E70000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/sun/nio/cs/ext/sjis0213.dat -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/META-INF/services/java.nio.charset.spi.CharsetProvider @OPENJDK7@/build/linux-amd64/gensrc/sun/nio/cs/ext/*.class @@ -752,7 +752,7 @@ assembly.class } { -out:IKVM.OpenJDK.Util.dll - -baseaddress:0x5A5C0000 + -baseaddress:0x5A500000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/util/jar/pack/intrinsic.properties -recurse:resources.zip/sun/launcher/resources/* -resource:META-INF/services/java.nio.file.spi.FileSystemProvider=@OPENJDK7@/jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider @@ -775,7 +775,7 @@ assembly.class } { -out:IKVM.OpenJDK.Text.dll - -baseaddress:0x5AB90000 + -baseaddress:0x5AAD0000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/text/* @OPENJDK7@/build/linux-amd64/j2re-image/lib/ext/localedata.jar @OPENJDK7@/jdk/src/share/classes/java/text/*.class @@ -787,7 +787,7 @@ assembly.class } { -out:IKVM.OpenJDK.Security.dll - -baseaddress:0x5AE00000 + -baseaddress:0x5AD40000 -remap:security.xml sun/security/jgss/wrapper/*.class @OPENJDK7@/jdk/src/share/classes/com/sun/crypto/provider/*.class @@ -858,7 +858,7 @@ assembly.class } { -out:IKVM.OpenJDK.Management.dll - -baseaddress:0x5B610000 + -baseaddress:0x5B550000 com/sun/management/*.class java/lang/management/*.class sun/management/*.class @@ -892,7 +892,7 @@ assembly.class } { -out:IKVM.OpenJDK.Misc.dll - -baseaddress:0x5B970000 + -baseaddress:0x5B8B0000 -resource:com/sun/servicetag/resources/javase_5_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties -resource:com/sun/servicetag/resources/javase_6_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties -resource:com/sun/servicetag/resources/javase_7_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties @@ -993,7 +993,7 @@ assembly.class } { -out:IKVM.OpenJDK.Naming.dll - -baseaddress:0x5BA90000 + -baseaddress:0x5B9D0000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/ldap/jndiprovider.properties -resource:META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor=@OPENJDK7@/jdk/src/share/classes/sun/net/spi/nameservice/dns/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor sun/net/dns/*.class @@ -1019,7 +1019,7 @@ assembly.class } { -out:IKVM.OpenJDK.Jdbc.dll - -baseaddress:0x5BBE0000 + -baseaddress:0x5BB20000 -resource:META-INF/services/java.sql.Driver=resources/META-INF/services/java.sql.Driver -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/rowset/* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/sql/* @@ -1037,7 +1037,7 @@ assembly.class } { -out:IKVM.OpenJDK.Remoting.dll - -baseaddress:0x5BD30000 + -baseaddress:0x5BC70000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/rmi/* @OPENJDK7@/build/linux-amd64/classes/sun/rmi/registry/*.class @OPENJDK7@/build/linux-amd64/classes/sun/rmi/server/*.class @@ -1063,7 +1063,7 @@ assembly.class } { -out:IKVM.OpenJDK.Beans.dll - -baseaddress:0x5BE50000 + -baseaddress:0x5BD90000 @OPENJDK7@/build/linux-amd64/impsrc/com/sun/activation/registries/*.class @OPENJDK7@/build/linux-amd64/impsrc/javax/activation/*.class @OPENJDK7@/jdk/src/share/classes/com/sun/beans/*.class @@ -1076,7 +1076,7 @@ assembly.class } { -out:IKVM.OpenJDK.Media.dll - -baseaddress:0x5BF10000 + -baseaddress:0x5BE50000 -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.print.* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.sound.* -recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/imageio/plugins/common/iio-plugin.properties diff --git a/external/ikvm/openjdk/sun/awt/AppContext.java b/external/ikvm/openjdk/sun/awt/AppContext.java index be6734e492..23c86c90f0 100644 --- a/external/ikvm/openjdk/sun/awt/AppContext.java +++ b/external/ikvm/openjdk/sun/awt/AppContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,7 @@ import sun.util.logging.PlatformLogger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.atomic.AtomicInteger; /** * The AppContext is a table referenced by ThreadGroup which stores @@ -129,7 +130,7 @@ import java.util.concurrent.locks.ReentrantLock; * @author Thomas Ball * @author Fred Ecks */ -public final class AppContext extends AppContextDC { +public final class AppContext { private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.AppContext"); /* Since the contents of an AppContext are unique to each Java @@ -161,8 +162,9 @@ public final class AppContext extends AppContextDC { } /* The main "system" AppContext, used by everything not otherwise - contained in another AppContext. - */ + contained in another AppContext. It is implicitly created for + standalone apps only (i.e. not applets) + */ private static volatile AppContext mainAppContext = null; /* @@ -188,31 +190,16 @@ public final class AppContext extends AppContextDC { public static final String DISPOSED_PROPERTY_NAME = "disposed"; public static final String GUI_DISPOSED = "guidisposed"; - private volatile boolean isDisposed = false; // true if AppContext is disposed + private enum State { + VALID, + BEING_DISPOSED, + DISPOSED + }; - public boolean isDisposed() { - return isDisposed; - } + private volatile State state = State.VALID; - static { - // On the main Thread, we get the ThreadGroup, make a corresponding - // AppContext, and instantiate the Java EventQueue. This way, legacy - // code is unaffected by the move to multiple AppContext ability. - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ThreadGroup currentThreadGroup = - Thread.currentThread().getThreadGroup(); - ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); - while (parentThreadGroup != null) { - // Find the root ThreadGroup to construct our main AppContext - currentThreadGroup = parentThreadGroup; - parentThreadGroup = currentThreadGroup.getParent(); - } - mainAppContext = new AppContext(currentThreadGroup); - numAppContexts = 1; - return mainAppContext; - } - }); + public boolean isDisposed() { + return state == State.DISPOSED; } /* @@ -222,7 +209,7 @@ public final class AppContext extends AppContextDC { * number is 1. If so, it returns the sole AppContext without * checking Thread.currentThread(). */ - private static volatile int numAppContexts; + private static final AtomicInteger numAppContexts = new AtomicInteger(0); /* * The context ClassLoader that was used to create this AppContext. @@ -243,7 +230,7 @@ public final class AppContext extends AppContextDC { * @since 1.2 */ AppContext(ThreadGroup threadGroup) { - numAppContexts++; + numAppContexts.incrementAndGet(); this.threadGroup = threadGroup; threadGroup2appContext.put(threadGroup, this); @@ -266,6 +253,27 @@ public final class AppContext extends AppContextDC { private static final ThreadLocal<AppContext> threadAppContext = new ThreadLocal<AppContext>(); + private final static void initMainAppContext() { + // On the main Thread, we get the ThreadGroup, make a corresponding + // AppContext, and instantiate the Java EventQueue. This way, legacy + // code is unaffected by the move to multiple AppContext ability. + AccessController.doPrivileged(new PrivilegedAction<Void>() { + public Void run() { + ThreadGroup currentThreadGroup = + Thread.currentThread().getThreadGroup(); + ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); + while (parentThreadGroup != null) { + // Find the root ThreadGroup to construct our main AppContext + currentThreadGroup = parentThreadGroup; + parentThreadGroup = currentThreadGroup.getParent(); + } + + mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup); + return null; + } + }); + } + /** * Returns the appropriate AppContext for the caller, * as determined by its ThreadGroup. If the main "system" AppContext @@ -278,8 +286,10 @@ public final class AppContext extends AppContextDC { * @since 1.2 */ public final static AppContext getAppContext() { - if (numAppContexts == 1) // If there's only one system-wide, - return mainAppContext; // return the main system AppContext. + // we are standalone app, return the main app context + if (numAppContexts.get() == 1 && mainAppContext != null) { + return mainAppContext; + } AppContext appContext = threadAppContext.get(); @@ -293,29 +303,37 @@ public final class AppContext extends AppContextDC { // when new AppContext objects are created. ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); ThreadGroup threadGroup = currentThreadGroup; + + // Special case: we implicitly create the main app context + // if no contexts have been created yet. This covers standalone apps + // and excludes applets because by the time applet starts + // a number of contexts have already been created by the plugin. + if (numAppContexts.get() == 0) { + // This check is not necessary, its purpose is to help + // Plugin devs to catch all the cases of main AC creation. + if (System.getProperty("javaplugin.version") == null && + System.getProperty("javawebstart.version") == null) { + initMainAppContext(); + } + } + AppContext context = threadGroup2appContext.get(threadGroup); while (context == null) { threadGroup = threadGroup.getParent(); if (threadGroup == null) { - // If we get here, we're running under a ThreadGroup that - // has no AppContext associated with it. This should never - // happen, because createNewContext() should be used by the - // toolkit to create the ThreadGroup that everything runs - // under. - throw new RuntimeException("Invalid ThreadGroup"); + return null; } context = threadGroup2appContext.get(threadGroup); } + // In case we did anything in the above while loop, we add // all the intermediate ThreadGroups to threadGroup2appContext // so we won't spin again. for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { threadGroup2appContext.put(tg, context); } + // Now we're done, so we cache the latest key/value pair. - // (we do this before checking with any AWTSecurityManager, so if - // this Thread equates with the main AppContext in the cache, it - // still will) threadAppContext.set(context); return context; @@ -323,33 +341,30 @@ public final class AppContext extends AppContextDC { }); } - if (appContext == mainAppContext) { - // Before we return the main "system" AppContext, check to - // see if there's an AWTSecurityManager installed. If so, - // allow it to choose the AppContext to return. - SecurityManager securityManager = System.getSecurityManager(); - if ((securityManager != null) && - (securityManager instanceof AWTSecurityManager)) - { - AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager; - AppContext secAppContext = awtSecMgr.getAppContext(); - if (secAppContext != null) { - appContext = secAppContext; // Return what we're told - } - } - } - return appContext; } /** - * Returns the main ("system") AppContext. + * Returns true if the specified AppContext is the main AppContext. * - * @return the main AppContext + * @param ctx the context to compare with the main context + * @return true if the specified AppContext is the main AppContext. * @since 1.8 */ - final static AppContext getMainAppContext() { - return mainAppContext; + public final static boolean isMainContext(AppContext ctx) { + return (ctx != null && ctx == mainAppContext); + } + + private final static AppContext getExecutionAppContext() { + SecurityManager securityManager = System.getSecurityManager(); + if ((securityManager != null) && + (securityManager instanceof AWTSecurityManager)) + { + AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager; + AppContext secAppContext = awtSecMgr.getAppContext(); + return secAppContext; // Return what we're told + } + return null; } private long DISPOSAL_TIMEOUT = 5000; // Default to 5-second timeout @@ -383,10 +398,11 @@ public final class AppContext extends AppContextDC { } synchronized(this) { - if (this.isDisposed) { - return; // If already disposed, bail. + if (this.state != State.VALID) { + return; // If already disposed or being disposed, bail. } - this.isDisposed = true; + + this.state = State.BEING_DISPOSED; } final PropertyChangeSupport changeSupport = this.changeSupport; @@ -401,6 +417,27 @@ public final class AppContext extends AppContextDC { Runnable runnable = new Runnable() { public void run() { + Window[] windowsToDispose = Window.getOwnerlessWindows(); + for (Window w : windowsToDispose) { + try { + w.dispose(); + } catch (Throwable t) { + log.finer("exception occured while disposing app context", t); + } + } + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + if (!GraphicsEnvironment.isHeadless() && SystemTray.isSupported()) + { + SystemTray systemTray = SystemTray.getSystemTray(); + TrayIcon[] trayIconsToDispose = systemTray.getTrayIcons(); + for (TrayIcon ti : trayIconsToDispose) { + systemTray.remove(ti); + } + } + return null; + } + }); // Alert PropertyChangeListeners that the GUI has been disposed. if (changeSupport != null) { changeSupport.firePropertyChange(GUI_DISPOSED, false, true); @@ -435,6 +472,11 @@ public final class AppContext extends AppContextDC { } catch (InterruptedException e) { } } + // We are done with posting events, so change the state to disposed + synchronized(this) { + this.state = State.DISPOSED; + } + // Next, we interrupt all Threads in the ThreadGroup this.threadGroup.interrupt(); // Note, the EventDispatchThread we've interrupted may dump an @@ -492,7 +534,7 @@ public final class AppContext extends AppContextDC { this.table.clear(); // Clear out the Hashtable to ease garbage collection } - numAppContexts--; + numAppContexts.decrementAndGet(); mostRecentKeyValue = null; } @@ -766,6 +808,50 @@ public final class AppContext extends AppContextDC { } return changeSupport.getPropertyChangeListeners(propertyName); } + + // Set up JavaAWTAccess in SharedSecrets + static { + sun.misc.SharedSecrets.setJavaAWTAccess(new sun.misc.JavaAWTAccess() { + public Object get(Object key) { + AppContext ac = getAppContext(); + return (ac == null) ? null : ac.get(key); + } + public void put(Object key, Object value) { + AppContext ac = getAppContext(); + if (ac != null) { + ac.put(key, value); + } + } + public void remove(Object key) { + AppContext ac = getAppContext(); + if (ac != null) { + ac.remove(key); + } + } + public boolean isDisposed() { + AppContext ac = getAppContext(); + return (ac == null) ? true : ac.isDisposed(); + } + public boolean isMainAppContext() { + return (numAppContexts.get() == 1 && mainAppContext != null); + } + public Object getContext() { + return getAppContext(); + } + public Object getExecutionContext() { + return getExecutionAppContext(); + } + public Object get(Object context, Object key) { + return ((AppContext)context).get(key); + } + public void put(Object context, Object key, Object value) { + ((AppContext)context).put(key, value); + } + public void remove(Object context, Object key) { + ((AppContext)context).remove(key); + } + }); + } } final class MostRecentKeyValue { diff --git a/external/ikvm/openjdk/sun/awt/AppContextDC.java b/external/ikvm/openjdk/sun/awt/AppContextDC.java deleted file mode 100644 index 47e71d627d..0000000000 --- a/external/ikvm/openjdk/sun/awt/AppContextDC.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -package sun.awt; - -/* This class exists to decouple java.util.TimeZone from sun.awt.AppContext */ -public abstract class AppContextDC -{ - public abstract boolean isDisposed(); - public abstract Object get(Object key); - public abstract Object put(Object key, Object value); - public abstract Object remove(Object key); - - public static AppContextDC getAppContext() - { - try - { - return (AppContextDC)Class.forName("sun.awt.AppContext").getMethod("getAppContext").invoke(null); - } - catch (Exception _) - { - return null; - } - } -} diff --git a/external/ikvm/openjdk/sun/awt/SunToolkit.java b/external/ikvm/openjdk/sun/awt/SunToolkit.java index fa457d5309..11612ec1ee 100644 --- a/external/ikvm/openjdk/sun/awt/SunToolkit.java +++ b/external/ikvm/openjdk/sun/awt/SunToolkit.java @@ -64,7 +64,7 @@ public abstract class SunToolkit extends Toolkit implements WindowClosingSupport, WindowClosingListener, ComponentFactory, InputMethodSupport, KeyboardFocusManagerPeerProvider { - private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.SunToolkit"); + // 8014736: logging has been removed from SunToolkit /** * Special mask for the UngrabEvent events, in addition to the @@ -97,6 +97,14 @@ public abstract class SunToolkit extends Toolkit */ public final static int MAX_BUTTONS_SUPPORTED = 20; + /** + * Creates and initializes EventQueue instance for the specified + * AppContext. + * Note that event queue must be created from createNewAppContext() + * only in order to ensure that EventQueue constructor obtains + * the correct AppContext. + * @param appContext AppContext to associate with the event queue + */ private static void initEQ(AppContext appContext) { EventQueue eventQueue; @@ -117,8 +125,6 @@ public abstract class SunToolkit extends Toolkit } public SunToolkit() { - // 7122796: Always create an EQ for the main AppContext - initEQ(AppContext.getMainAppContext()); } public boolean useBufferPerWindow() { @@ -277,11 +283,14 @@ public abstract class SunToolkit extends Toolkit */ public static AppContext createNewAppContext() { ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + return createNewAppContext(threadGroup); + } + + static final AppContext createNewAppContext(ThreadGroup threadGroup) { // Create appContext before initialization of EventQueue, so all // the calls to AppContext.getAppContext() from EventQueue ctor // return correct values AppContext appContext = new AppContext(threadGroup); - initEQ(appContext); return appContext; @@ -512,10 +521,6 @@ public abstract class SunToolkit extends Toolkit // otherwise have to be modified to precisely identify // system-generated events. setSystemGenerated(event); - AppContext eventContext = targetToAppContext(event.getSource()); - if (eventContext != null && !eventContext.equals(appContext)) { - log.fine("Event posted on wrong app context : " + event); - } PostEventQueue postEventQueue = (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); if (postEventQueue != null) { @@ -544,20 +549,28 @@ public abstract class SunToolkit extends Toolkit * EventQueue yet. */ public static void flushPendingEvents() { + AppContext appContext = AppContext.getAppContext(); + flushPendingEvents(appContext); + } + + public static void flushPendingEvents(AppContext appContext) { flushLock.lock(); try { // Don't call flushPendingEvents() recursively if (!isFlushingPendingEvents) { isFlushingPendingEvents = true; - AppContext appContext = AppContext.getAppContext(); - PostEventQueue postEventQueue = - (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); - if (postEventQueue != null) { - postEventQueue.flush(); + try { + PostEventQueue postEventQueue = + (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); + if (postEventQueue != null) { + postEventQueue.flush(); + } + } + finally { + isFlushingPendingEvents = false; } } } finally { - isFlushingPendingEvents = false; flushLock.unlock(); } } @@ -798,10 +811,6 @@ public abstract class SunToolkit extends Toolkit //with scale factors x1, x3/4, x2/3, xN, x1/N. Image im = i.next(); if (im == null) { - if (log.isLoggable(PlatformLogger.FINER)) { - log.finer("SunToolkit.getScaledIconImage: " + - "Skipping the image passed into Java because it's null."); - } continue; } if (im instanceof ToolkitImage) { @@ -814,10 +823,6 @@ public abstract class SunToolkit extends Toolkit iw = im.getWidth(null); ih = im.getHeight(null); } catch (Exception e){ - if (log.isLoggable(PlatformLogger.FINER)) { - log.finer("SunToolkit.getScaledIconImage: " + - "Perhaps the image passed into Java is broken. Skipping this icon."); - } continue; } if (iw > 0 && ih > 0) { @@ -889,14 +894,6 @@ public abstract class SunToolkit extends Toolkit try { int x = (width - bestWidth) / 2; int y = (height - bestHeight) / 2; - if (log.isLoggable(PlatformLogger.FINER)) { - log.finer("WWindowPeer.getScaledIconData() result : " + - "w : " + width + " h : " + height + - " iW : " + bestImage.getWidth(null) + " iH : " + bestImage.getHeight(null) + - " sim : " + bestSimilarity + " sf : " + bestScaleFactor + - " adjW : " + bestWidth + " adjH : " + bestHeight + - " x : " + x + " y : " + y); - } g.drawImage(bestImage, x, y, bestWidth, bestHeight, null); } finally { g.dispose(); @@ -907,10 +904,6 @@ public abstract class SunToolkit extends Toolkit public static DataBufferInt getScaledIconData(java.util.List<Image> imageList, int width, int height) { BufferedImage bimage = getScaledIconImage(imageList, width, height); if (bimage == null) { - if (log.isLoggable(PlatformLogger.FINER)) { - log.finer("SunToolkit.getScaledIconData: " + - "Perhaps the image passed into Java is broken. Skipping this icon."); - } return null; } Raster raster = bimage.getRaster(); @@ -1768,25 +1761,6 @@ public abstract class SunToolkit extends Toolkit return (Window)comp; } - /** - * Returns the value of the system property indicated by the specified key. - */ - public static String getSystemProperty(final String key) { - return (String)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(key); - } - }); - } - - /** - * Returns the boolean value of the system property indicated by the specified key. - */ - protected static Boolean getBooleanSystemProperty(String key) { - return Boolean.valueOf(AccessController. - doPrivileged(new GetBooleanAction(key))); - } - private static Boolean sunAwtDisableMixing = null; /** @@ -1795,7 +1769,8 @@ public abstract class SunToolkit extends Toolkit */ public synchronized static boolean getSunAwtDisableMixing() { if (sunAwtDisableMixing == null) { - sunAwtDisableMixing = getBooleanSystemProperty("sun.awt.disableMixing"); + sunAwtDisableMixing = AccessController.doPrivileged( + new GetBooleanAction("sun.awt.disableMixing")); } return sunAwtDisableMixing.booleanValue(); } @@ -1809,6 +1784,28 @@ public abstract class SunToolkit extends Toolkit return false; } + private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object(); + + public synchronized void setWindowDeactivationTime(Window w, long time) { + AppContext ctx = getAppContext(w); + WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY); + if (map == null) { + map = new WeakHashMap<Window, Long>(); + ctx.put(DEACTIVATION_TIMES_MAP_KEY, map); + } + map.put(w, time); + } + + public synchronized long getWindowDeactivationTime(Window w) { + AppContext ctx = getAppContext(w); + WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY); + if (map == null) { + return -1; + } + Long time = map.get(w); + return time == null ? -1 : time; + } + // Cosntant alpha public boolean isWindowOpacitySupported() { return false; @@ -1829,6 +1826,13 @@ public abstract class SunToolkit extends Toolkit } /** + * Returns true if swing backbuffer should be translucent. + */ + public boolean isSwingBackbufferTranslucencySupported() { + return false; + } + + /** * Returns whether or not a containing top level window for the passed * component is * {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT PERPIXEL_TRANSLUCENT}. @@ -1949,25 +1953,41 @@ class PostEventQueue { private EventQueueItem queueTail = null; private final EventQueue eventQueue; + // For the case when queue is cleared but events are not posted + private volatile boolean isFlushing = false; + PostEventQueue(EventQueue eq) { eventQueue = eq; } public synchronized boolean noEvents() { - return queueHead == null; + return queueHead == null && !isFlushing; } /* * Continually post pending AWTEvents to the Java EventQueue. The method * is synchronized to ensure the flush is completed before a new event * can be posted to this queue. + * + * 7177040: The method couldn't be wholly synchronized because of calls + * of EventQueue.postEvent() that uses pushPopLock, otherwise it could + * potentially lead to deadlock */ - public synchronized void flush() { - EventQueueItem tempQueue = queueHead; - queueHead = queueTail = null; - while (tempQueue != null) { - eventQueue.postEvent(tempQueue.event); - tempQueue = tempQueue.next; + public void flush() { + EventQueueItem tempQueue; + synchronized (this) { + tempQueue = queueHead; + queueHead = queueTail = null; + isFlushing = (tempQueue != null); + } + try { + while (tempQueue != null) { + eventQueue.postEvent(tempQueue.event); + tempQueue = tempQueue.next; + } + } + finally { + isFlushing = false; } } diff --git a/external/ikvm/openjdk/sun/awt/image/ByteComponentRaster.java b/external/ikvm/openjdk/sun/awt/image/ByteComponentRaster.java deleted file mode 100644 index 912542a7bf..0000000000 --- a/external/ikvm/openjdk/sun/awt/image/ByteComponentRaster.java +++ /dev/null @@ -1,919 +0,0 @@ -/* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.awt.image; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.awt.image.RasterFormatException; -import java.awt.image.SampleModel; -import java.awt.image.ComponentSampleModel; -import java.awt.image.SinglePixelPackedSampleModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.Rectangle; -import java.awt.Point; - -/** - * This class defines a Raster with pixels consisting of one or more 8-bit - * data elements stored in close proximity to each other in a single byte - * array. - * The bit precision per data element is that - * of the data type (that is, the bit precision for this Raster is 8). - * There is only one pixel stride and one scanline stride for all - * bands. This type of Raster can be used with a - * ComponentColorModel if there are multiple bands, or an - * IndexColorModel if there is only one band. - * <p> - * For example, 3-3-2 RGB image data can be represented by a - * ByteComponentRaster using a SinglePixelPackedSampleModel and - * a ComponentColorModel. - * - */ -public class ByteComponentRaster extends SunWritableRaster { - - /** private band offset for use by native code */ - protected int bandOffset; - - /** Data offsets for each band of image data. */ - protected int[] dataOffsets; - - /** Scanline stride of the image data contained in this Raster. */ - protected int scanlineStride; - - /** Pixel stride of the image data contained in this Raster. */ - protected int pixelStride; - - /** The image data array. */ - protected byte[] data; - - int type; - - /** A cached copy of minX + width for use in bounds checks. */ - private int maxX; - - /** A cached copy of minY + height for use in bounds checks. */ - private int maxY; - - /** - * Constructs a ByteComponentRaster with the given SampleModel. - * The Raster's upper left corner is origin and it is the same - * size as the SampleModel. A DataBuffer large enough to describe the - * Raster is automatically created. SampleModel must be of type - * SinglePixelPackedSampleModel or ComponentSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param origin The Point that specified the origin. - */ - public ByteComponentRaster(SampleModel sampleModel, Point origin) { - this(sampleModel, - sampleModel.createDataBuffer(), - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a ByteComponentRaster with the given SampleModel - * and DataBuffer. The Raster's upper left corner is origin and - * it is the same size as the SampleModel. The DataBuffer is not - * initialized and must be a DataBufferByte compatible with SampleModel. - * SampleModel must be of type SinglePixelPackedSampleModel - * or ComponentSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferShort that contains the image data. - * @param origin The Point that specifies the origin. - */ - public ByteComponentRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Point origin) { - this(sampleModel, - dataBuffer, - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a ByteComponentRaster with the given SampleModel, - * DataBuffer, and parent. DataBuffer must be a DataBufferByte and - * SampleModel must be of type SinglePixelPackedSampleModel - * or ComponentSampleModel. - * When translated into the base Raster's - * coordinate system, aRegion must be contained by the base Raster. - * Origin is the coordinate in the new Raster's coordinate system of - * the origin of the base Raster. (The base Raster is the Raster's - * ancestor which has no parent.) - * - * Note that this constructor should generally be called by other - * constructors or create methods, it should not be used directly. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferShort that contains the image data. - * @param aRegion The Rectangle that specifies the image area. - * @param origin The Point that specifies the origin. - * @param parent The parent (if any) of this raster. - */ - public ByteComponentRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Rectangle aRegion, - Point origin, - ByteComponentRaster parent) { - super(sampleModel, dataBuffer, aRegion, origin, parent); - this.maxX = minX + width; - this.maxY = minY + height; - - if (!(dataBuffer instanceof DataBufferByte)) { - throw new RasterFormatException("ByteComponentRasters must have " + - "byte DataBuffers"); - } - - DataBufferByte dbb = (DataBufferByte)dataBuffer; - this.data = stealData(dbb, 0); - if (dbb.getNumBanks() != 1) { - throw new - RasterFormatException("DataBuffer for ByteComponentRasters"+ - " must only have 1 bank."); - } - int dbOffset = dbb.getOffset(); - - if (sampleModel instanceof ComponentSampleModel) { - ComponentSampleModel ism = (ComponentSampleModel)sampleModel; - this.type = IntegerComponentRaster.TYPE_BYTE_SAMPLES; - this.scanlineStride = ism.getScanlineStride(); - this.pixelStride = ism.getPixelStride(); - this.dataOffsets = ism.getBandOffsets(); - int xOffset = aRegion.x - origin.x; - int yOffset = aRegion.y - origin.y; - for (int i = 0; i < getNumDataElements(); i++) { - dataOffsets[i] += dbOffset + - xOffset*pixelStride+yOffset*scanlineStride; - } - } else if (sampleModel instanceof SinglePixelPackedSampleModel) { - SinglePixelPackedSampleModel sppsm = - (SinglePixelPackedSampleModel)sampleModel; - this.type = IntegerComponentRaster.TYPE_BYTE_PACKED_SAMPLES; - this.scanlineStride = sppsm.getScanlineStride(); - this.pixelStride = 1; - this.dataOffsets = new int[1]; - this.dataOffsets[0] = dbOffset; - int xOffset = aRegion.x - origin.x; - int yOffset = aRegion.y - origin.y; - dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride; - } else { - throw new RasterFormatException("IntegerComponentRasters must " + - "have ComponentSampleModel or SinglePixelPackedSampleModel"); - } - this.bandOffset = this.dataOffsets[0]; - - verify(false); - } - - /** - * Returns a copy of the data offsets array. For each band the data offset - * is the index into the band's data array, of the first sample of the - * band. - */ - public int[] getDataOffsets() { - return (int[]) dataOffsets.clone(); - } - - /** - * Returns the data offset for the specified band. The data offset - * is the index into the data array - * in which the first sample of the first scanline is stored. - * @param band The band whose offset is returned. - */ - public int getDataOffset(int band) { - return dataOffsets[band]; - } - - /** - * Returns the scanline stride -- the number of data array elements between - * a given sample and the sample in the same column of the next row in the - * same band. - */ - public int getScanlineStride() { - return scanlineStride; - } - - /** - * Returns pixel stride -- the number of data array elements between two - * samples for the same band on the same scanline. - */ - public int getPixelStride() { - return pixelStride; - } - - /** - * Returns a reference to the data array. - */ - public byte[] getDataStorage() { - return data; - } - - /** - * Returns the data elements for all bands at the specified - * location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param outData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - byte outData[]; - if (obj == null) { - outData = new byte[numDataElements]; - } else { - outData = (byte[])obj; - } - int off = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - - for (int band = 0; band < numDataElements; band++) { - outData[band] = data[dataOffsets[band] + off]; - } - - return outData; - } - - /** - * Returns an array of data elements from the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * <pre> - * byte[] bandData = (byte[])raster.getDataElements(x, y, w, h, null); - * int numDataElements = raster.getNumDataElements(); - * byte[] pixel = new byte[numDataElements]; - * // To find a data element at location (x2, y2) - * System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements, - * pixel, 0, numDataElements); - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param outData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getDataElements(int x, int y, int w, int h, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - byte outData[]; - if (obj == null) { - outData = new byte[w*h*numDataElements]; - } else { - outData = (byte[])obj; - } - - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - outData[off++] = data[dataOffsets[c] + xoff]; - } - } - } - - return outData; - } - - /** - * Returns a byte array of data elements from the specified rectangular - * region for the specified band. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * <pre> - * byte[] bandData = raster.getByteData(x, y, w, h, null); - * // To find the data element at location (x2, y2) - * byte bandElement = bandData[((y2-y)*w + (x2-x))]; - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param band The band to return. - * @param outData If non-null, data elements for all bands - * at the specified location are returned in this array. - * @return Data array with data elements for all bands. - */ - public byte[] getByteData(int x, int y, int w, int h, - int band, byte[] outData) { - // Bounds check for 'band' will be performed automatically - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - if (outData == null) { - outData = new byte[scanlineStride*h]; - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride + dataOffsets[band]; - int xoff; - int off = 0; - int xstart; - int ystart; - - if (pixelStride == 1) { - if (scanlineStride == w) { - System.arraycopy(data, yoff, outData, 0, w*h); - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - System.arraycopy(data, yoff, outData, off, w); - off += w; - } - } - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - outData[off++] = data[xoff]; - } - } - } - - return outData; - } - - /** - * Returns a byte array of data elements from the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * <pre> - * byte[] bandData = raster.getByteData(x, y, w, h, null); - * int numDataElements = raster.getnumDataElements(); - * byte[] pixel = new byte[numDataElements]; - * // To find a data element at location (x2, y2) - * System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements, - * pixel, 0, numDataElements); - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param outData If non-null, data elements for all bands - * at the specified location are returned in this array. - * @return Data array with data elements for all bands. - */ - public byte[] getByteData(int x, int y, int w, int h, byte[] outData) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - if (outData == null) { - outData = new byte[numDataElements*scanlineStride*h]; - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - // REMIND: Should keep track if dataOffsets are in a nice order - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - outData[off++] = data[dataOffsets[c] + xoff]; - } - } - } - - return outData; - } - - /** - * Stores the data elements for all bands at the specified location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements() - * containing the pixel data to place at x,y. - */ - public void setDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - byte inData[] = (byte[])obj; - int off = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - - for (int i = 0; i < numDataElements; i++) { - data[dataOffsets[i] + off] = inData[i]; - } - - markDirty(); - } - - /** - * Stores the Raster data at the specified location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inRaster Raster of data to place at x,y location. - */ - public void setDataElements(int x, int y, Raster inRaster) { - int dstOffX = inRaster.getMinX() + x; - int dstOffY = inRaster.getMinY() + y; - int width = inRaster.getWidth(); - int height = inRaster.getHeight(); - if ((dstOffX < this.minX) || (dstOffY < this.minY) || - (dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - - setDataElements(dstOffX, dstOffY, width, height, inRaster); - } - - /** - * Stores the Raster data at the specified location. - * @param dstX The absolute X coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param dstY The absolute Y coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param width The number of pixels to store horizontally - * @param height The number of pixels to store vertically - * @param inRaster Raster of data to place at x,y location. - */ - private void setDataElements(int dstX, int dstY, - int width, int height, - Raster inRaster) { - // Assume bounds checking has been performed previously - if (width <= 0 || height <= 0) { - return; - } - - int srcOffX = inRaster.getMinX(); - int srcOffY = inRaster.getMinY(); - Object tdata = null; - - if (inRaster instanceof ByteComponentRaster) { - ByteComponentRaster bct = (ByteComponentRaster) inRaster; - byte[] bdata = bct.getDataStorage(); - // REMIND: Do something faster! - if (numDataElements == 1) { - int toff = bct.getDataOffset(0); - int tss = bct.getScanlineStride(); - - int srcOffset = toff; - int dstOffset = dataOffsets[0]+(dstY-minY)*scanlineStride+ - (dstX-minX); - - - if (pixelStride == bct.getPixelStride()) { - width *= pixelStride; - for (int tmpY=0; tmpY < height; tmpY++) { - System.arraycopy(bdata, srcOffset, - data, dstOffset, width); - srcOffset += tss; - dstOffset += scanlineStride; - } - markDirty(); - return; - } - } - } - - for (int startY=0; startY < height; startY++) { - // Grab one scanline at a time - tdata = inRaster.getDataElements(srcOffX, srcOffY+startY, - width, 1, tdata); - setDataElements(dstX, dstY+startY, width, 1, tdata); - } - } - - /** - * Stores an array of data elements into the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * for the nth band at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))*numDataElements + n] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param inData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements() - * containing the pixel data to place between x,y and - * x+h, y+h. - */ - public void setDataElements(int x, int y, int w, int h, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - byte inData[] = (byte[])obj; - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - if (numDataElements == 1) { - int srcOffset = 0; - int dstOffset = yoff + dataOffsets[0]; - for (ystart=0; ystart < h; ystart++) { - xoff = yoff; - System.arraycopy(inData, srcOffset, - data, dstOffset, w); - - srcOffset += w; - dstOffset += scanlineStride; - } - markDirty(); - return; - } - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - data[dataOffsets[c] + xoff] = inData[off++]; - } - } - } - - markDirty(); - } - - /** - * Stores a byte array of data elements into the specified rectangular - * region for the specified band. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x)) + n] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param band The band to set. - * @param inData The data elements to be stored. - */ - public void putByteData(int x, int y, int w, int h, - int band, byte[] inData) { - // Bounds check for 'band' will be performed automatically - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride + dataOffsets[band]; - int xoff; - int off = 0; - int xstart; - int ystart; - - if (pixelStride == 1) { - if (scanlineStride == w) { - System.arraycopy(inData, 0, data, yoff, w*h); - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - System.arraycopy(inData, off, data, yoff, w); - off += w; - } - } - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - data[xoff] = inData[off++]; - } - } - } - - markDirty(); - } - - /** - * Stores a byte array of data elements into the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * for the nth band at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))*numDataElements + n] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param inData The data elements to be stored. - */ - public void putByteData(int x, int y, int w, int h, byte[] inData) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - - int xoff; - int off = 0; - int xstart; - int ystart; - - if (numDataElements == 1) { - yoff += dataOffsets[0]; - if (pixelStride == 1) { - if (scanlineStride == w) { - System.arraycopy(inData, 0, data, yoff, w*h); - } - else { - for (ystart=0; ystart < h; ystart++) { - System.arraycopy(inData, off, data, yoff, w); - off += w; - yoff += scanlineStride; - } - } - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - data[xoff] = inData[off++]; - } - } - } - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - data[dataOffsets[c] + xoff] = inData[off++]; - } - } - } - } - - markDirty(); - } - - /** - * Creates a subraster given a region of the raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this raster to the upper-left corner - * of the subraster. A subset of the bands of the parent Raster may - * be specified. If this is null, then all the bands are present in the - * subRaster. A translation to the subRaster may also be specified. - * Note that the subraster will reference the same - * DataBuffer as the parent raster, but using different offsets. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subraster. - * @param y0 Translated Y origin of the subraster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent raster. - */ - public Raster createChild(int x, int y, - int width, int height, - int x0, int y0, int[] bandList) { - WritableRaster newRaster = createWritableChild(x, y, - width, height, - x0, y0, - bandList); - return (Raster) newRaster; - } - - /** - * Creates a Writable subRaster given a region of the Raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this Raster to the upper-left corner - * of the subRaster. A subset of the bands of the parent Raster may - * be specified. If this is null, then all the bands are present in the - * subRaster. A translation to the subRaster may also be specified. - * Note that the subRaster will reference the same - * DataBuffer as the parent Raster, but using different offsets. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subraster. - * @param y0 Translated Y origin of the subraster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent Raster. - */ - public WritableRaster createWritableChild(int x, int y, - int width, int height, - int x0, int y0, - int[] bandList) { - if (x < this.minX) { - throw new RasterFormatException("x lies outside the raster"); - } - if (y < this.minY) { - throw new RasterFormatException("y lies outside the raster"); - } - if ((x+width < x) || (x+width > this.minX + this.width)) { - throw new RasterFormatException("(x + width) is outside of Raster"); - } - if ((y+height < y) || (y+height > this.minY + this.height)) { - throw new RasterFormatException("(y + height) is outside of Raster"); - } - - SampleModel sm; - - if (bandList != null) - sm = sampleModel.createSubsetSampleModel(bandList); - else - sm = sampleModel; - - int deltaX = x0 - x; - int deltaY = y0 - y; - - return new ByteComponentRaster(sm, - dataBuffer, - new Rectangle(x0, y0, width, height), - new Point(sampleModelTranslateX+deltaX, - sampleModelTranslateY+deltaY), - this); - } - - /** - * Creates a Raster with the same layout but using a different - * width and height, and with new zeroed data arrays. - */ - public WritableRaster createCompatibleWritableRaster(int w, int h) { - if (w <= 0 || h <=0) { - throw new RasterFormatException("negative "+ - ((w <= 0) ? "width" : "height")); - } - - SampleModel sm = sampleModel.createCompatibleSampleModel(w, h); - - return new ByteComponentRaster(sm , new Point(0,0)); - - } - - /** - * Creates a Raster with the same layout and the same - * width and height, and with new zeroed data arrays. If - * the Raster is a subRaster, this will call - * createCompatibleRaster(width, height). - */ - public WritableRaster createCompatibleWritableRaster() { - return createCompatibleWritableRaster(width,height); - } - - /** - * Verify that the layout parameters are consistent with - * the data. If strictCheck - * is false, this method will check for ArrayIndexOutOfBounds conditions. If - * strictCheck is true, this method will check for additional error - * conditions such as line wraparound (width of a line greater than - * the scanline stride). - * @return String Error string, if the layout is incompatible with - * the data. Otherwise returns null. - */ - private void verify (boolean strictCheck) { - // Make sure data for Raster is in a legal range - for (int i=0; i < dataOffsets.length; i++) { - if (dataOffsets[i] < 0) { - throw new RasterFormatException("Data offsets for band "+i+ - "("+dataOffsets[i]+ - ") must be >= 0"); - } - } - - int maxSize = 0; - int size; - - for (int i=0; i < numDataElements; i++) { - size = (height-1)*scanlineStride + (width-1)*pixelStride + - dataOffsets[i]; - if (size > maxSize) { - maxSize = size; - } - } - if (data.length < maxSize) { - throw new RasterFormatException("Data array too small (should be "+ - maxSize+" )"); - } - } - - public String toString() { - return new String ("ByteComponentRaster: width = "+width+" height = " - + height - +" #numDataElements "+numDataElements - // +" xOff = "+xOffset+" yOff = "+yOffset - +" dataOff[0] = "+dataOffsets[0]); - } - -// /** -// * For debugging... prints a region of a one-band ByteComponentRaster -// */ -// public void print(int x, int y, int w, int h) { -// // REMIND: Only works for 1 band! -// System.out.println(this); -// int offset = dataOffsets[0] + y*scanlineStride + x*pixelStride; -// int off; -// for (int yoff=0; yoff < h; yoff++, offset += scanlineStride) { -// off = offset; -// System.out.print("Line "+(y+yoff)+": "); -// for (int xoff = 0; xoff < w; xoff++, off+= pixelStride) { -// String s = Integer.toHexString(data[off]); -// if (s.length() == 8) { -// s = s.substring(6,8); -// } -// System.out.print(s+" "); -// } -// System.out.println(""); -// } -// } - - -} diff --git a/external/ikvm/openjdk/sun/awt/image/BytePackedRaster.java b/external/ikvm/openjdk/sun/awt/image/BytePackedRaster.java deleted file mode 100644 index 25c84f42a0..0000000000 --- a/external/ikvm/openjdk/sun/awt/image/BytePackedRaster.java +++ /dev/null @@ -1,1389 +0,0 @@ -/* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.awt.image; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.awt.image.RasterFormatException; -import java.awt.image.SampleModel; -import java.awt.image.MultiPixelPackedSampleModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.Rectangle; -import java.awt.Point; - -/** - * This class is useful for describing 1, 2, or 4 bit image data - * elements. This raster has one band whose pixels are packed - * together into individual bytes in a single byte array. This type - * of raster can be used with an IndexColorModel. This raster uses a - * MultiPixelPackedSampleModel. - * - */ -public class BytePackedRaster extends SunWritableRaster { - - /** The data bit offset for each pixel. */ - int dataBitOffset; - - /** Scanline stride of the image data contained in this Raster. */ - int scanlineStride; - - /** - * The bit stride of a pixel, equal to the total number of bits - * required to store a pixel. - */ - int pixelBitStride; - - /** The bit mask for extracting the pixel. */ - int bitMask; - - /** The image data array. */ - byte[] data; - - /** 8 minus the pixel bit stride. */ - int shiftOffset; - - int type; - - /** A cached copy of minX + width for use in bounds checks. */ - private int maxX; - - /** A cached copy of minY + height for use in bounds checks. */ - private int maxY; - - /** - * Constructs a BytePackedRaster with the given SampleModel. - * The Raster's upper left corner is origin and it is the same - * size as the SampleModel. A DataBuffer large enough to describe the - * Raster is automatically created. SampleModel must be of type - * MultiPixelPackedSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param origin The Point that specified the origin. - */ - public BytePackedRaster(SampleModel sampleModel, - Point origin) { - this(sampleModel, - sampleModel.createDataBuffer(), - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a BytePackedRaster with the given SampleModel - * and DataBuffer. The Raster's upper left corner is origin and - * it is the same size as the SampleModel. The DataBuffer is not - * initialized and must be a DataBufferByte compatible with SampleModel. - * SampleModel must be of type MultiPixelPackedSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferShort that contains the image data. - * @param origin The Point that specifies the origin. - */ - public BytePackedRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Point origin) { - this(sampleModel, - dataBuffer, - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a BytePackedRaster with the given SampleModel, - * DataBuffer, and parent. DataBuffer must be a DataBufferByte and - * SampleModel must be of type MultiPixelPackedSampleModel. - * When translated into the base Raster's - * coordinate system, aRegion must be contained by the base Raster. - * Origin is the coordinate in the new Raster's coordinate system of - * the origin of the base Raster. (The base Raster is the Raster's - * ancestor which has no parent.) - * - * Note that this constructor should generally be called by other - * constructors or create methods, it should not be used directly. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferShort that contains the image data. - * @param aRegion The Rectangle that specifies the image area. - * @param origin The Point that specifies the origin. - * @param parent The parent (if any) of this raster. - * - * @exception RasterFormatException if the parameters do not conform - * to requirements of this Raster type. - */ - public BytePackedRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Rectangle aRegion, - Point origin, - BytePackedRaster parent){ - super(sampleModel,dataBuffer,aRegion,origin, parent); - this.maxX = minX + width; - this.maxY = minY + height; - - if (!(dataBuffer instanceof DataBufferByte)) { - throw new RasterFormatException("BytePackedRasters must have" + - "byte DataBuffers"); - } - DataBufferByte dbb = (DataBufferByte)dataBuffer; - this.data = stealData(dbb, 0); - if (dbb.getNumBanks() != 1) { - throw new - RasterFormatException("DataBuffer for BytePackedRasters"+ - " must only have 1 bank."); - } - int dbOffset = dbb.getOffset(); - - if (sampleModel instanceof MultiPixelPackedSampleModel) { - MultiPixelPackedSampleModel mppsm = - (MultiPixelPackedSampleModel)sampleModel; - this.type = IntegerComponentRaster.TYPE_BYTE_BINARY_SAMPLES; - pixelBitStride = mppsm.getPixelBitStride(); - if (pixelBitStride != 1 && - pixelBitStride != 2 && - pixelBitStride != 4) { - throw new RasterFormatException - ("BytePackedRasters must have a bit depth of 1, 2, or 4"); - } - scanlineStride = mppsm.getScanlineStride(); - dataBitOffset = mppsm.getDataBitOffset() + dbOffset*8; - int xOffset = aRegion.x - origin.x; - int yOffset = aRegion.y - origin.y; - dataBitOffset += xOffset*pixelBitStride + yOffset*scanlineStride*8; - bitMask = (1 << pixelBitStride) -1; - shiftOffset = 8 - pixelBitStride; - } else { - throw new RasterFormatException("BytePackedRasters must have"+ - "MultiPixelPackedSampleModel"); - } - verify(false); - } - - /** - * Returns the data bit offset for the Raster. The data - * bit offset is the bit index into the data array element - * corresponding to the first sample of the first scanline. - */ - public int getDataBitOffset() { - return dataBitOffset; - } - - /** - * Returns the scanline stride -- the number of data array elements between - * a given sample and the sample in the same column - * of the next row. - */ - public int getScanlineStride() { - return scanlineStride; - } - - /** - * Returns pixel bit stride -- the number of bits between two - * samples on the same scanline. - */ - public int getPixelBitStride() { - return pixelBitStride; - } - - /** - * Returns a reference to the entire data array. - */ - public byte[] getDataStorage() { - return data; - } - - /** - * Returns the data element at the specified - * location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param outData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - byte outData[]; - if (obj == null) { - outData = new byte[numDataElements]; - } else { - outData = (byte[])obj; - } - int bitnum = dataBitOffset + (x-minX) * pixelBitStride; - // Fix 4184283 - int element = data[(y-minY) * scanlineStride + (bitnum >> 3)] & 0xff; - int shift = shiftOffset - (bitnum & 7); - outData[0] = (byte)((element >> shift) & bitMask); - return outData; - } - - /** - * Returns the pixel data for the specified rectangle of pixels in a - * primitive array of type TransferType. - * For image data supported by the Java 2D API, this - * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or - * DataBuffer.TYPE_INT. Data may be returned in a packed format, - * thus increasing efficiency for data transfers. - * - * An ArrayIndexOutOfBoundsException may be thrown - * if the coordinates are not in bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of TransferType. - * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer) - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param outData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements(). - * If null, an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the requested pixel data. - */ - public Object getDataElements(int x, int y, int w, int h, - Object outData) { - return getByteData(x, y, w, h, (byte[])outData); - } - - /** - * Returns an array of data elements from the specified rectangular - * region. - * - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * <pre> - * byte[] bandData = (byte[])raster.getPixelData(x, y, w, h, null); - * int pixel; - * // To find a data element at location (x2, y2) - * pixel = bandData[((y2-y)*w + (x2-x))]; - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param outData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getPixelData(int x, int y, int w, int h, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - byte outData[]; - if (obj == null) { - outData = new byte[numDataElements*w*h]; - } else { - outData = (byte[])obj; - } - int pixbits = pixelBitStride; - int scanbit = dataBitOffset + (x-minX) * pixbits; - int index = (y-minY) * scanlineStride; - int outindex = 0; - byte data[] = this.data; - - for (int j = 0; j < h; j++) { - int bitnum = scanbit; - for (int i = 0; i < w; i++) { - int shift = shiftOffset - (bitnum & 7); - outData[outindex++] = - (byte)(bitMask & (data[index + (bitnum >> 3)] >> shift)); - bitnum += pixbits; - } - index += scanlineStride; - } - return outData; - } - - /** - * Returns a byte array containing the specified data elements - * from the data array. The band index will be ignored. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * <pre> - * byte[] byteData = getByteData(x, y, band, w, h, null); - * // To find a data element at location (x2, y2) - * byte element = byteData[(y2-y)*w + (x2-x)]; - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param band The band to return, is ignored. - * @param outData If non-null, data elements - * at the specified locations are returned in this array. - * @return Byte array with data elements. - */ - public byte[] getByteData(int x, int y, int w, int h, - int band, byte[] outData) { - return getByteData(x, y, w, h, outData); - } - - /** - * Returns a byte array containing the specified data elements - * from the data array. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * <pre> - * byte[] byteData = raster.getByteData(x, y, w, h, null); - * byte pixel; - * // To find a data element at location (x2, y2) - * pixel = byteData[((y2-y)*w + (x2-x))]; - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param outData If non-null, data elements - * at the specified locations are returned in this array. - * @return Byte array with data elements. - */ - public byte[] getByteData(int x, int y, int w, int h, byte[] outData) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - if (outData == null) { - outData = new byte[w * h]; - } - int pixbits = pixelBitStride; - int scanbit = dataBitOffset + (x-minX) * pixbits; - int index = (y-minY) * scanlineStride; - int outindex = 0; - byte data[] = this.data; - - for (int j = 0; j < h; j++) { - int bitnum = scanbit; - int element; - - // Process initial portion of scanline - int i = 0; - while ((i < w) && ((bitnum & 7) != 0)) { - int shift = shiftOffset - (bitnum & 7); - outData[outindex++] = - (byte)(bitMask & (data[index + (bitnum >> 3)] >> shift)); - bitnum += pixbits; - i++; - } - - // Process central portion of scanline 8 pixels at a time - int inIndex = index + (bitnum >> 3); - switch (pixbits) { - case 1: - for (; i < w - 7; i += 8) { - element = data[inIndex++]; - outData[outindex++] = (byte)((element >> 7) & 1); - outData[outindex++] = (byte)((element >> 6) & 1); - outData[outindex++] = (byte)((element >> 5) & 1); - outData[outindex++] = (byte)((element >> 4) & 1); - outData[outindex++] = (byte)((element >> 3) & 1); - outData[outindex++] = (byte)((element >> 2) & 1); - outData[outindex++] = (byte)((element >> 1) & 1); - outData[outindex++] = (byte)(element & 1); - bitnum += 8; - } - break; - - case 2: - for (; i < w - 7; i += 8) { - element = data[inIndex++]; - outData[outindex++] = (byte)((element >> 6) & 3); - outData[outindex++] = (byte)((element >> 4) & 3); - outData[outindex++] = (byte)((element >> 2) & 3); - outData[outindex++] = (byte)(element & 3); - - element = data[inIndex++]; - outData[outindex++] = (byte)((element >> 6) & 3); - outData[outindex++] = (byte)((element >> 4) & 3); - outData[outindex++] = (byte)((element >> 2) & 3); - outData[outindex++] = (byte)(element & 3); - - bitnum += 16; - } - break; - - case 4: - for (; i < w - 7; i += 8) { - element = data[inIndex++]; - outData[outindex++] = (byte)((element >> 4) & 0xf); - outData[outindex++] = (byte)(element & 0xf); - - element = data[inIndex++]; - outData[outindex++] = (byte)((element >> 4) & 0xf); - outData[outindex++] = (byte)(element & 0xf); - - element = data[inIndex++]; - outData[outindex++] = (byte)((element >> 4) & 0xf); - outData[outindex++] = (byte)(element & 0xf); - - element = data[inIndex++]; - outData[outindex++] = (byte)((element >> 4) & 0xf); - outData[outindex++] = (byte)(element & 0xf); - - bitnum += 32; - } - break; - } - - // Process final portion of scanline - for (; i < w; i++) { - int shift = shiftOffset - (bitnum & 7); - outData[outindex++] = - (byte) (bitMask & (data[index + (bitnum >> 3)] >> shift)); - bitnum += pixbits; - } - - index += scanlineStride; - } - - return outData; - } - - /** - * Stores the data elements at the specified location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements() - * containing the pixel data to place at x,y. - */ - public void setDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - byte inData[] = (byte[])obj; - int bitnum = dataBitOffset + (x-minX) * pixelBitStride; - int index = (y-minY) * scanlineStride + (bitnum >> 3); - int shift = shiftOffset - (bitnum & 7); - - byte element = data[index]; - element &= ~(bitMask << shift); - element |= (inData[0] & bitMask) << shift; - data[index] = element; - - markDirty(); - } - - /** - * Stores the Raster data at the specified location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inRaster Raster of data to place at x,y location. - */ - public void setDataElements(int x, int y, Raster inRaster) { - // Check if we can use fast code - if (!(inRaster instanceof BytePackedRaster) || - ((BytePackedRaster)inRaster).pixelBitStride != pixelBitStride) { - super.setDataElements(x, y, inRaster); - return; - } - - int srcOffX = inRaster.getMinX(); - int srcOffY = inRaster.getMinY(); - int dstOffX = srcOffX + x; - int dstOffY = srcOffY + y; - int width = inRaster.getWidth(); - int height = inRaster.getHeight(); - if ((dstOffX < this.minX) || (dstOffY < this.minY) || - (dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - setDataElements(dstOffX, dstOffY, - srcOffX, srcOffY, - width, height, - (BytePackedRaster)inRaster); - } - - /** - * Stores the Raster data at the specified location. - * @param dstX The absolute X coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param dstY The absolute Y coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param srcX The absolute X coordinate of the upper-left source - * pixel that will be copied into this Raster - * @param srcY The absolute Y coordinate of the upper-left source - * pixel that will be copied into this Raster - * @param width The number of pixels to store horizontally - * @param height The number of pixels to store vertically - * @param inRaster BytePackedRaster of data to place at x,y location. - */ - private void setDataElements(int dstX, int dstY, - int srcX, int srcY, - int width, int height, - BytePackedRaster inRaster) { - // Assume bounds checking has been performed previously - if (width <= 0 || height <= 0) { - return; - } - - byte[] inData = inRaster.data; - byte[] outData = this.data; - - int inscan = inRaster.scanlineStride; - int outscan = this.scanlineStride; - int inbit = inRaster.dataBitOffset + - 8 * (srcY - inRaster.minY) * inscan + - (srcX - inRaster.minX) * inRaster.pixelBitStride; - int outbit = (this.dataBitOffset + - 8 * (dstY - minY) * outscan + - (dstX - minX) * this.pixelBitStride); - int copybits = width * pixelBitStride; - - // Check whether the same bit alignment is present in both - // Rasters; if so, we can copy whole bytes using - // System.arraycopy. If not, we must do a "funnel shift" - // where adjacent bytes contribute to each destination byte. - if ((inbit & 7) == (outbit & 7)) { - // copy is bit aligned - int bitpos = outbit & 7; - if (bitpos != 0) { - int bits = 8 - bitpos; - // Copy partial bytes on left - int inbyte = inbit >> 3; - int outbyte = outbit >> 3; - int mask = 0xff >> bitpos; - if (copybits < bits) { - // Fix bug 4399076: previously had '8 - copybits' instead - // of 'bits - copybits'. - // - // Prior to the this expression, 'mask' has its rightmost - // 'bits' bits set to '1'. We want it to have a total - // of 'copybits' bits set, therefore we want to introduce - // 'bits - copybits' zeroes on the right. - mask &= 0xff << (bits - copybits); - bits = copybits; - } - for (int j = 0; j < height; j++) { - int element = outData[outbyte]; - element &= ~mask; - element |= (inData[inbyte] & mask); - outData[outbyte] = (byte) element; - inbyte += inscan; - outbyte += outscan; - } - inbit += bits; - outbit += bits; - copybits -= bits; - } - if (copybits >= 8) { - // Copy whole bytes - int inbyte = inbit >> 3; - int outbyte = outbit >> 3; - int copybytes = copybits >> 3; - if (copybytes == inscan && inscan == outscan) { - System.arraycopy(inData, inbyte, - outData, outbyte, - inscan * height); - } else { - for (int j = 0; j < height; j++) { - System.arraycopy(inData, inbyte, - outData, outbyte, - copybytes); - inbyte += inscan; - outbyte += outscan; - } - } - - int bits = copybytes*8; - inbit += bits; - outbit += bits; - copybits -= bits; - } - if (copybits > 0) { - // Copy partial bytes on right - int inbyte = inbit >> 3; - int outbyte = outbit >> 3; - int mask = (0xff00 >> copybits) & 0xff; - for (int j = 0; j < height; j++) { - int element = outData[outbyte]; - element &= ~mask; - element |= (inData[inbyte] & mask); - outData[outbyte] = (byte) element; - inbyte += inscan; - outbyte += outscan; - } - } - } else { - // Unaligned case, see RFE #4284166 - // Note that the code in that RFE is not correct - - // Insert bits into the first byte of the output - // if either the starting bit position is not zero or - // we are writing fewer than 8 bits in total - int bitpos = outbit & 7; - if (bitpos != 0 || copybits < 8) { - int bits = 8 - bitpos; - int inbyte = inbit >> 3; - int outbyte = outbit >> 3; - - int lshift = inbit & 7; - int rshift = 8 - lshift; - int mask = 0xff >> bitpos; - if (copybits < bits) { - // Fix mask if we're only writing a partial byte - mask &= 0xff << (bits - copybits); - bits = copybits; - } - int lastByte = inData.length - 1; - for (int j = 0; j < height; j++) { - // Read two bytes from the source if possible - // Don't worry about going over a scanline boundary - // since any extra bits won't get used anyway - byte inData0 = inData[inbyte]; - byte inData1 = (byte)0; - if (inbyte < lastByte) { - inData1 = inData[inbyte + 1]; - } - - // Insert the new bits into the output - int element = outData[outbyte]; - element &= ~mask; - element |= (((inData0 << lshift) | - ((inData1 & 0xff) >> rshift)) - >> bitpos) & mask; - outData[outbyte] = (byte)element; - inbyte += inscan; - outbyte += outscan; - } - - inbit += bits; - outbit += bits; - copybits -= bits; - } - - // Now we have outbit & 7 == 0 so we can write - // complete bytes for a while - - // Make sure we have work to do in the central loop - // to avoid reading past the end of the scanline - if (copybits >= 8) { - int inbyte = inbit >> 3; - int outbyte = outbit >> 3; - int copybytes = copybits >> 3; - int lshift = inbit & 7; - int rshift = 8 - lshift; - - for (int j = 0; j < height; j++) { - int ibyte = inbyte + j*inscan; - int obyte = outbyte + j*outscan; - - int inData0 = inData[ibyte]; - // Combine adjacent bytes while 8 or more bits left - for (int i = 0; i < copybytes; i++) { - int inData1 = inData[ibyte + 1]; - int val = (inData0 << lshift) | - ((inData1 & 0xff) >> rshift); - outData[obyte] = (byte)val; - inData0 = inData1; - - ++ibyte; - ++obyte; - } - } - - int bits = copybytes*8; - inbit += bits; - outbit += bits; - copybits -= bits; - } - - // Finish last byte - if (copybits > 0) { - int inbyte = inbit >> 3; - int outbyte = outbit >> 3; - int mask = (0xff00 >> copybits) & 0xff; - int lshift = inbit & 7; - int rshift = 8 - lshift; - - int lastByte = inData.length - 1; - for (int j = 0; j < height; j++) { - byte inData0 = inData[inbyte]; - byte inData1 = (byte)0; - if (inbyte < lastByte) { - inData1 = inData[inbyte + 1]; - } - - // Insert the new bits into the output - int element = outData[outbyte]; - element &= ~mask; - element |= ((inData0 << lshift) | - ((inData1 & 0xff) >> rshift)) & mask; - outData[outbyte] = (byte)element; - - inbyte += inscan; - outbyte += outscan; - } - } - } - - markDirty(); - } - - /** - * Copies pixels from Raster srcRaster to this WritableRaster. - * For each (x, y) address in srcRaster, the corresponding pixel - * is copied to address (x+dx, y+dy) in this WritableRaster, - * unless (x+dx, y+dy) falls outside the bounds of this raster. - * srcRaster must have the same number of bands as this WritableRaster. - * The copy is a simple copy of source samples to the corresponding - * destination samples. For details, see - * {@link WritableRaster#setRect(Raster)}. - * - * @param dx The X translation factor from src space to dst space - * of the copy. - * @param dy The Y translation factor from src space to dst space - * of the copy. - * @param srcRaster The Raster from which to copy pixels. - */ - public void setRect(int dx, int dy, Raster srcRaster) { - // Check if we can use fast code - if (!(srcRaster instanceof BytePackedRaster) || - ((BytePackedRaster)srcRaster).pixelBitStride != pixelBitStride) { - super.setRect(dx, dy, srcRaster); - return; - } - - int width = srcRaster.getWidth(); - int height = srcRaster.getHeight(); - int srcOffX = srcRaster.getMinX(); - int srcOffY = srcRaster.getMinY(); - int dstOffX = dx+srcOffX; - int dstOffY = dy+srcOffY; - - // Clip to this raster - if (dstOffX < this.minX) { - int skipX = this.minX - dstOffX; - width -= skipX; - srcOffX += skipX; - dstOffX = this.minX; - } - if (dstOffY < this.minY) { - int skipY = this.minY - dstOffY; - height -= skipY; - srcOffY += skipY; - dstOffY = this.minY; - } - if (dstOffX+width > this.maxX) { - width = this.maxX - dstOffX; - } - if (dstOffY+height > this.maxY) { - height = this.maxY - dstOffY; - } - - setDataElements(dstOffX, dstOffY, - srcOffX, srcOffY, - width, height, - (BytePackedRaster)srcRaster); - } - - /** - * Stores an array of data elements into the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param inData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements() - * containing the pixel data to place between x,y and - * x+h, y+h. - */ - public void setDataElements(int x, int y, int w, int h, Object obj) { - putByteData(x, y, w, h, (byte[])obj); - } - - /** - * Stores a byte array of data elements into the specified rectangular - * region. The band index will be ignored. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param band The band to set, is ignored. - * @param inData The data elements to be stored. - */ - public void putByteData(int x, int y, int w, int h, - int band, byte[] inData) { - putByteData(x, y, w, h, inData); - } - - /** - * Stores a byte array of data elements into the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param inData The data elements to be stored. - */ - public void putByteData(int x, int y, int w, int h, byte[] inData) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - if (w == 0 || h == 0) { - return; - } - - int pixbits = pixelBitStride; - int scanbit = dataBitOffset + (x - minX) * pixbits; - int index = (y - minY) * scanlineStride; - int outindex = 0; - byte data[] = this.data; - for (int j = 0; j < h; j++) { - int bitnum = scanbit; - int element; - - // Process initial portion of scanline - int i = 0; - while ((i < w) && ((bitnum & 7) != 0)) { - int shift = shiftOffset - (bitnum & 7); - element = data[index + (bitnum >> 3)]; - element &= ~(bitMask << shift); - element |= (inData[outindex++] & bitMask) << shift; - data[index + (bitnum >> 3)] = (byte)element; - - bitnum += pixbits; - i++; - } - - // Process central portion of scanline 8 pixels at a time - int inIndex = index + (bitnum >> 3); - switch (pixbits) { - case 1: - for (; i < w - 7; i += 8) { - element = (inData[outindex++] & 1) << 7; - element |= (inData[outindex++] & 1) << 6; - element |= (inData[outindex++] & 1) << 5; - element |= (inData[outindex++] & 1) << 4; - element |= (inData[outindex++] & 1) << 3; - element |= (inData[outindex++] & 1) << 2; - element |= (inData[outindex++] & 1) << 1; - element |= (inData[outindex++] & 1); - - data[inIndex++] = (byte)element; - - bitnum += 8; - } - break; - - case 2: - for (; i < w - 7; i += 8) { - element = (inData[outindex++] & 3) << 6; - element |= (inData[outindex++] & 3) << 4; - element |= (inData[outindex++] & 3) << 2; - element |= (inData[outindex++] & 3); - data[inIndex++] = (byte)element; - - element = (inData[outindex++] & 3) << 6; - element |= (inData[outindex++] & 3) << 4; - element |= (inData[outindex++] & 3) << 2; - element |= (inData[outindex++] & 3); - data[inIndex++] = (byte)element; - - bitnum += 16; - } - break; - - case 4: - for (; i < w - 7; i += 8) { - element = (inData[outindex++] & 0xf) << 4; - element |= (inData[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - element = (inData[outindex++] & 0xf) << 4; - element |= (inData[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - element = (inData[outindex++] & 0xf) << 4; - element |= (inData[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - element = (inData[outindex++] & 0xf) << 4; - element |= (inData[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - bitnum += 32; - } - break; - } - - // Process final portion of scanline - for (; i < w; i++) { - int shift = shiftOffset - (bitnum & 7); - - element = data[index + (bitnum >> 3)]; - element &= ~(bitMask << shift); - element |= (inData[outindex++] & bitMask) << shift; - data[index + (bitnum >> 3)] = (byte)element; - - bitnum += pixbits; - } - - index += scanlineStride; - } - - markDirty(); - } - - /** - * Returns an int array containing all samples for a rectangle of pixels, - * one sample per array element. - * An ArrayIndexOutOfBoundsException may be thrown - * if the coordinates are not in bounds. - * @param x, y the coordinates of the upper-left pixel location - * @param w Width of the pixel rectangle - * @param h Height of the pixel rectangle - * @param iArray An optionally pre-allocated int array - * @return the samples for the specified rectangle of pixels. - */ - public int[] getPixels(int x, int y, int w, int h, int iArray[]) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - if (iArray == null) { - iArray = new int[w * h]; - } - int pixbits = pixelBitStride; - int scanbit = dataBitOffset + (x-minX) * pixbits; - int index = (y-minY) * scanlineStride; - int outindex = 0; - byte data[] = this.data; - - for (int j = 0; j < h; j++) { - int bitnum = scanbit; - int element; - - // Process initial portion of scanline - int i = 0; - while ((i < w) && ((bitnum & 7) != 0)) { - int shift = shiftOffset - (bitnum & 7); - iArray[outindex++] = - bitMask & (data[index + (bitnum >> 3)] >> shift); - bitnum += pixbits; - i++; - } - - // Process central portion of scanline 8 pixels at a time - int inIndex = index + (bitnum >> 3); - switch (pixbits) { - case 1: - for (; i < w - 7; i += 8) { - element = data[inIndex++]; - iArray[outindex++] = (element >> 7) & 1; - iArray[outindex++] = (element >> 6) & 1; - iArray[outindex++] = (element >> 5) & 1; - iArray[outindex++] = (element >> 4) & 1; - iArray[outindex++] = (element >> 3) & 1; - iArray[outindex++] = (element >> 2) & 1; - iArray[outindex++] = (element >> 1) & 1; - iArray[outindex++] = element & 1; - bitnum += 8; - } - break; - - case 2: - for (; i < w - 7; i += 8) { - element = data[inIndex++]; - iArray[outindex++] = (element >> 6) & 3; - iArray[outindex++] = (element >> 4) & 3; - iArray[outindex++] = (element >> 2) & 3; - iArray[outindex++] = element & 3; - - element = data[inIndex++]; - iArray[outindex++] = (element >> 6) & 3; - iArray[outindex++] = (element >> 4) & 3; - iArray[outindex++] = (element >> 2) & 3; - iArray[outindex++] = element & 3; - - bitnum += 16; - } - break; - - case 4: - for (; i < w - 7; i += 8) { - element = data[inIndex++]; - iArray[outindex++] = (element >> 4) & 0xf; - iArray[outindex++] = element & 0xf; - - element = data[inIndex++]; - iArray[outindex++] = (element >> 4) & 0xf; - iArray[outindex++] = element & 0xf; - - element = data[inIndex++]; - iArray[outindex++] = (element >> 4) & 0xf; - iArray[outindex++] = element & 0xf; - - element = data[inIndex++]; - iArray[outindex++] = (element >> 4) & 0xf; - iArray[outindex++] = element & 0xf; - - bitnum += 32; - } - break; - } - - // Process final portion of scanline - for (; i < w; i++) { - int shift = shiftOffset - (bitnum & 7); - iArray[outindex++] = - bitMask & (data[index + (bitnum >> 3)] >> shift); - bitnum += pixbits; - } - - index += scanlineStride; - } - - return iArray; - } - - /** - * Sets all samples for a rectangle of pixels from an int array containing - * one sample per array element. - * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are - * not in bounds. - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param iArray The input int pixel array. - */ - public void setPixels(int x, int y, int w, int h, int iArray[]) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int pixbits = pixelBitStride; - int scanbit = dataBitOffset + (x - minX) * pixbits; - int index = (y - minY) * scanlineStride; - int outindex = 0; - byte data[] = this.data; - for (int j = 0; j < h; j++) { - int bitnum = scanbit; - int element; - - // Process initial portion of scanline - int i = 0; - while ((i < w) && ((bitnum & 7) != 0)) { - int shift = shiftOffset - (bitnum & 7); - element = data[index + (bitnum >> 3)]; - element &= ~(bitMask << shift); - element |= (iArray[outindex++] & bitMask) << shift; - data[index + (bitnum >> 3)] = (byte)element; - - bitnum += pixbits; - i++; - } - - // Process central portion of scanline 8 pixels at a time - int inIndex = index + (bitnum >> 3); - switch (pixbits) { - case 1: - for (; i < w - 7; i += 8) { - element = (iArray[outindex++] & 1) << 7; - element |= (iArray[outindex++] & 1) << 6; - element |= (iArray[outindex++] & 1) << 5; - element |= (iArray[outindex++] & 1) << 4; - element |= (iArray[outindex++] & 1) << 3; - element |= (iArray[outindex++] & 1) << 2; - element |= (iArray[outindex++] & 1) << 1; - element |= (iArray[outindex++] & 1); - data[inIndex++] = (byte)element; - - bitnum += 8; - } - break; - - case 2: - for (; i < w - 7; i += 8) { - element = (iArray[outindex++] & 3) << 6; - element |= (iArray[outindex++] & 3) << 4; - element |= (iArray[outindex++] & 3) << 2; - element |= (iArray[outindex++] & 3); - data[inIndex++] = (byte)element; - - element = (iArray[outindex++] & 3) << 6; - element |= (iArray[outindex++] & 3) << 4; - element |= (iArray[outindex++] & 3) << 2; - element |= (iArray[outindex++] & 3); - data[inIndex++] = (byte)element; - - bitnum += 16; - } - break; - - case 4: - for (; i < w - 7; i += 8) { - element = (iArray[outindex++] & 0xf) << 4; - element |= (iArray[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - element = (iArray[outindex++] & 0xf) << 4; - element |= (iArray[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - element = (iArray[outindex++] & 0xf) << 4; - element |= (iArray[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - element = (iArray[outindex++] & 0xf) << 4; - element |= (iArray[outindex++] & 0xf); - data[inIndex++] = (byte)element; - - bitnum += 32; - } - break; - } - - // Process final portion of scanline - for (; i < w; i++) { - int shift = shiftOffset - (bitnum & 7); - - element = data[index + (bitnum >> 3)]; - element &= ~(bitMask << shift); - element |= (iArray[outindex++] & bitMask) << shift; - data[index + (bitnum >> 3)] = (byte)element; - - bitnum += pixbits; - } - - index += scanlineStride; - } - - markDirty(); - } - - /** - * Creates a subraster given a region of the raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this raster to the upper-left corner - * of the subraster. Note that the subraster will reference the same - * DataBuffer as the parent raster, but using different offsets. The - * bandList is ignored. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subraster. - * @param y0 Translated Y origin of the subraster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent raster. - */ - public Raster createChild(int x, int y, - int width, int height, - int x0, int y0, int[] bandList) { - WritableRaster newRaster = createWritableChild(x, y, - width, height, - x0, y0, - bandList); - return (Raster) newRaster; - } - - /** - * Creates a Writable subRaster given a region of the Raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this Raster to the upper-left corner - * of the subRaster. The bandList is ignored. - * A translation to the subRaster may also be specified. - * Note that the subRaster will reference the same - * DataBuffer as the parent Raster, but using different offsets. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subraster. - * @param y0 Translated Y origin of the subraster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent Raster. - */ - public WritableRaster createWritableChild(int x, int y, - int width, int height, - int x0, int y0, - int[] bandList) { - if (x < this.minX) { - throw new RasterFormatException("x lies outside the raster"); - } - if (y < this.minY) { - throw new RasterFormatException("y lies outside the raster"); - } - if ((x+width < x) || (x+width > this.minX + this.width)) { - throw new RasterFormatException("(x + width) is outside of Raster"); - } - if ((y+height < y) || (y+height > this.minY + this.height)) { - throw new RasterFormatException("(y + height) is outside of Raster"); - } - - SampleModel sm; - - if (bandList != null) { - sm = sampleModel.createSubsetSampleModel(bandList); - } - else { - sm = sampleModel; - } - - int deltaX = x0 - x; - int deltaY = y0 - y; - - return new BytePackedRaster(sm, - dataBuffer, - new Rectangle(x0, y0, width, height), - new Point(sampleModelTranslateX+deltaX, - sampleModelTranslateY+deltaY), - this); - } - - /** - * Creates a raster with the same layout but using a different - * width and height, and with new zeroed data arrays. - */ - public WritableRaster createCompatibleWritableRaster(int w, int h) { - if (w <= 0 || h <=0) { - throw new RasterFormatException("negative "+ - ((w <= 0) ? "width" : "height")); - } - - SampleModel sm = sampleModel.createCompatibleSampleModel(w,h); - - return new BytePackedRaster(sm, new Point(0,0)); - } - - /** - * Creates a raster with the same layout and the same - * width and height, and with new zeroed data arrays. - */ - public WritableRaster createCompatibleWritableRaster () { - return createCompatibleWritableRaster(width,height); - } - - /** - * Verify that the layout parameters are consistent with - * the data. If strictCheck - * is false, this method will check for ArrayIndexOutOfBounds conditions. - * If strictCheck is true, this method will check for additional error - * conditions such as line wraparound (width of a line greater than - * the scanline stride). - * @return String Error string, if the layout is incompatible with - * the data. Otherwise returns null. - */ - private void verify (boolean strictCheck) { - // Make sure data for Raster is in a legal range - if (dataBitOffset < 0) { - throw new RasterFormatException("Data offsets must be >= 0"); - } - - int lastbit = (dataBitOffset - + (height-1) * scanlineStride * 8 - + (width-1) * pixelBitStride - + pixelBitStride - 1); - if (lastbit / 8 >= data.length) { - throw new RasterFormatException("raster dimensions overflow " + - "array bounds"); - } - if (strictCheck) { - if (height > 1) { - lastbit = width * pixelBitStride - 1; - if (lastbit / 8 >= scanlineStride) { - throw new RasterFormatException("data for adjacent" + - " scanlines overlaps"); - } - } - } - } - - public String toString() { - return new String ("BytePackedRaster: width = "+width+" height = "+height - +" #channels "+numBands - +" xOff = "+sampleModelTranslateX - +" yOff = "+sampleModelTranslateY); - } -} diff --git a/external/ikvm/openjdk/sun/awt/image/IntegerComponentRaster.java b/external/ikvm/openjdk/sun/awt/image/IntegerComponentRaster.java deleted file mode 100644 index 7c44c6f993..0000000000 --- a/external/ikvm/openjdk/sun/awt/image/IntegerComponentRaster.java +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.awt.image; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.awt.image.RasterFormatException; -import java.awt.image.SampleModel; -import java.awt.image.SinglePixelPackedSampleModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferInt; -import java.awt.Rectangle; -import java.awt.Point; - -/** - * This class defines a Raster with pixels consisting of one or more 32-bit - * data elements stored in close proximity to each other in a integer array. - * The bit precision per data element is that - * of the data type (that is, the bit precision for this raster is 32). - * There is only one pixel stride and one scanline stride for all - * bands. For a given pixel, all samples fit in N data elements and these - * N data elements hold samples for only one pixel. This type of Raster - * can be used with a PackedColorModel. - * <p> - * For example, if there is only one data element per pixel, a - * SinglePixelPackedSampleModel can be used to represent multiple - * bands with a PackedColorModel (including a DirectColorModel) for - * color interpretation. - * - */ -public class IntegerComponentRaster extends SunWritableRaster { - - static final int TYPE_CUSTOM = 0; - static final int TYPE_BYTE_SAMPLES = 1; - static final int TYPE_USHORT_SAMPLES = 2; - static final int TYPE_INT_SAMPLES = 3; - static final int TYPE_BYTE_BANDED_SAMPLES = 4; - static final int TYPE_USHORT_BANDED_SAMPLES = 5; - static final int TYPE_INT_BANDED_SAMPLES = 6; - static final int TYPE_BYTE_PACKED_SAMPLES = 7; - static final int TYPE_USHORT_PACKED_SAMPLES = 8; - static final int TYPE_INT_PACKED_SAMPLES = 9; - static final int TYPE_INT_8BIT_SAMPLES = 10; - static final int TYPE_BYTE_BINARY_SAMPLES = 11; - - /** private band offset for use by native code */ - protected int bandOffset; - - /** Data offsets for each band of image data. */ - protected int[] dataOffsets; - - /** Scanline stride of the image data contained in this Raster. */ - protected int scanlineStride; - - /** Pixel stride of the image data contained in this Raster. */ - protected int pixelStride; - - /** The image data array. */ - protected int[] data; - - /** The number of data elements required to store a pixel. */ - protected int numDataElems; - - int type; - - /** A cached copy of minX + width for use in bounds checks. */ - private int maxX; - - /** A cached copy of minY + height for use in bounds checks. */ - private int maxY; - - /** - * Constructs a IntegerComponentRaster with the given SampleModel. - * The Raster's upper left corner is origin and it is the same - * size as the SampleModel. A DataBuffer large enough to describe the - * Raster is automatically created. SampleModel must be of type - * SinglePixelPackedSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param origin The Point that specified the origin. - */ - public IntegerComponentRaster(SampleModel sampleModel, - Point origin) { - this(sampleModel, - sampleModel.createDataBuffer(), - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a IntegerComponentRaster with the given SampleModel - * and DataBuffer. The Raster's upper left corner is origin and - * it is the same sizes the SampleModel. The DataBuffer is not - * initialized and must be a DataBufferInt compatible with SampleModel. - * SampleModel must be of type SinglePixelPackedSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferInt that contains the image data. - * @param origin The Point that specifies the origin. - */ - public IntegerComponentRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Point origin) { - this(sampleModel, - dataBuffer, - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a IntegerComponentRaster with the given SampleModel, - * DataBuffer, and parent. DataBuffer must be a DataBufferInt and - * SampleModel must be of type SinglePixelPackedSampleModel. - * When translated into the base Raster's - * coordinate system, aRegion must be contained by the base Raster. - * Origin is the coodinate in the new Raster's coordinate system of - * the origin of the base Raster. (The base Raster is the Raster's - * ancestor which has no parent.) - * - * Note that this constructor should generally be called by other - * constructors or create methods, it should not be used directly. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferInt that contains the image data. - * @param aRegion The Rectangle that specifies the image area. - * @param origin The Point that specifies the origin. - * @param parent The parent (if any) of this raster. - */ - public IntegerComponentRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Rectangle aRegion, - Point origin, - IntegerComponentRaster parent){ - super(sampleModel,dataBuffer,aRegion,origin,parent); - this.maxX = minX + width; - this.maxY = minY + height; - if (!(dataBuffer instanceof DataBufferInt)) { - throw new RasterFormatException("IntegerComponentRasters must have" + - "integer DataBuffers"); - } - DataBufferInt dbi = (DataBufferInt)dataBuffer; - if (dbi.getNumBanks() != 1) { - throw new - RasterFormatException("DataBuffer for IntegerComponentRasters"+ - " must only have 1 bank."); - } - this.data = stealData(dbi, 0); - - if (sampleModel instanceof SinglePixelPackedSampleModel) { - SinglePixelPackedSampleModel sppsm = - (SinglePixelPackedSampleModel)sampleModel; - int[] boffsets = sppsm.getBitOffsets(); - boolean notByteBoundary = false; - for (int i=1; i < boffsets.length; i++) { - if ((boffsets[i]%8) != 0) { - notByteBoundary = true; - } - } - this.type = (notByteBoundary - ? IntegerComponentRaster.TYPE_INT_PACKED_SAMPLES - : IntegerComponentRaster.TYPE_INT_8BIT_SAMPLES); - - this.scanlineStride = sppsm.getScanlineStride(); - this.pixelStride = 1; - this.dataOffsets = new int[1]; - this.dataOffsets[0] = dbi.getOffset(); - this.bandOffset = this.dataOffsets[0]; - int xOffset = aRegion.x - origin.x; - int yOffset = aRegion.y - origin.y; - dataOffsets[0] += xOffset+yOffset*scanlineStride; - this.numDataElems = sppsm.getNumDataElements(); - } else { - throw new RasterFormatException("IntegerComponentRasters must have"+ - " SinglePixelPackedSampleModel"); - } - - verify(false); - } - - - /** - * Returns a copy of the data offsets array. For each band the data offset - * is the index into the band's data array, of the first sample of the - * band. - */ - public int[] getDataOffsets() { - return (int[]) dataOffsets.clone(); - } - - /** - * Returns data offset for the specified band. The data offset - * is the index into the data array in which the first sample - * of the first scanline is stored. - */ - public int getDataOffset(int band) { - return dataOffsets[band]; - } - - - /** - * Returns the scanline stride -- the number of data array elements between - * a given sample and the sample in the same column of the next row. - */ - public int getScanlineStride() { - return scanlineStride; - } - - /** - * Returns pixel stride -- the number of data array elements between two - * samples for the same band on the same scanline. - */ - public int getPixelStride() { - return pixelStride; - } - - /** - * Returns a reference to the data array. - */ - public int[] getDataStorage() { - return data; - } - - /** - * Returns the data elements for all bands at the specified - * location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param outData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int outData[]; - if (obj == null) { - outData = new int[numDataElements]; - } else { - outData = (int[])obj; - } - int off = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - for (int band = 0; band < numDataElements; band++) { - outData[band] = data[dataOffsets[band] + off]; - } - - return outData; - } - - - /** - * Returns an array of data elements from the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - <pre> - * int[] bandData = (int[])raster.getDataElements(x, y, w, h, null); - * int numDataElements = raster.getNumDataElements(); - * int[] pixel = new int[numDataElements]; - * // To find a data element at location (x2, y2) - * System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements, - * pixel, 0, numDataElements); - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param outData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getDataElements(int x, int y, int w, int h, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int outData[]; - if (obj instanceof int[]) { - outData = (int[])obj; - } else { - outData = new int[numDataElements*w*h]; - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - outData[off++] = data[dataOffsets[c] + xoff]; - } - } - } - - return outData; - } - - - /** - * Stores the data elements for all bands at the specified location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements() - * containing the pixel data to place at x,y. - */ - public void setDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int inData[] = (int[])obj; - - int off = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - - for (int i = 0; i < numDataElements; i++) { - data[dataOffsets[i] + off] = inData[i]; - } - - markDirty(); - } - - - /** - * Stores the Raster data at the specified location. - * The transferType of the inputRaster must match this raster. - * An ArrayIndexOutOfBoundsException will be thrown at runtime - * if the pixel coordinates are out of bounds. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inRaster Raster of data to place at x,y location. - */ - public void setDataElements(int x, int y, Raster inRaster) { - int dstOffX = x + inRaster.getMinX(); - int dstOffY = y + inRaster.getMinY(); - int width = inRaster.getWidth(); - int height = inRaster.getHeight(); - if ((dstOffX < this.minX) || (dstOffY < this.minY) || - (dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - setDataElements(dstOffX, dstOffY, width, height, inRaster); - } - - /** - * Stores the Raster data at the specified location. - * @param dstX The absolute X coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param dstY The absolute Y coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param width The number of pixels to store horizontally - * @param height The number of pixels to store vertically - * @param inRaster Raster of data to place at x,y location. - */ - private void setDataElements(int dstX, int dstY, - int width, int height, - Raster inRaster) { - // Assume bounds checking has been performed previously - if (width <= 0 || height <= 0) { - return; - } - - // Write inRaster (minX, minY) to (dstX, dstY) - - int srcOffX = inRaster.getMinX(); - int srcOffY = inRaster.getMinY(); - int tdata[] = null; - - if (inRaster instanceof IntegerComponentRaster && - (pixelStride == 1) && (numDataElements == 1)) { - IntegerComponentRaster ict = (IntegerComponentRaster) inRaster; - if (ict.getNumDataElements() != 1) { - throw new ArrayIndexOutOfBoundsException("Number of bands"+ - " does not match"); - } - - // Extract the raster parameters - tdata = ict.getDataStorage(); - int tss = ict.getScanlineStride(); - int toff = ict.getDataOffset(0); - - int srcOffset = toff; - - int dstOffset = dataOffsets[0]+(dstY-minY)*scanlineStride+ - (dstX-minX); - - - // Fastest case. We can copy scanlines - if (ict.getPixelStride() == pixelStride) { - width *= pixelStride; - - // Loop through all of the scanlines and copy the data - for (int startY=0; startY < height; startY++) { - System.arraycopy(tdata, srcOffset, data, dstOffset, width); - srcOffset += tss; - dstOffset += scanlineStride; - } - markDirty(); - return; - } - } - - Object odata = null; - for (int startY=0; startY < height; startY++) { - odata = inRaster.getDataElements(srcOffX, srcOffY+startY, - width, 1, odata); - setDataElements(dstX, dstY+startY, - width, 1, odata); - } - } - - /** - * Stores an array of data elements into the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * for the nth band at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))*numDataElements + n] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param inData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements() - * containing the pixel data to place between x,y and - * x+h, y+h. - */ - public void setDataElements(int x, int y, int w, int h, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int inData[] = (int[])obj; - - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - data[dataOffsets[c] + xoff] = inData[off++]; - } - } - } - - markDirty(); - } - - - /** - * Creates a subraster given a region of the raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this raster to the upper-left corner - * of the subraster. A subset of the bands of the parent Raster may - * be specified. If this is null, then all the bands are present in the - * subRaster. A translation to the subRaster may also be specified. - * Note that the subraster will reference the same - * DataBuffer as the parent raster, but using different offsets. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subraster. - * @param y0 Translated Y origin of the subraster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent raster. - */ - public WritableRaster createWritableChild (int x, int y, - int width, int height, - int x0, int y0, - int bandList[]) { - if (x < this.minX) { - throw new RasterFormatException("x lies outside raster"); - } - if (y < this.minY) { - throw new RasterFormatException("y lies outside raster"); - } - if ((x+width < x) || (x+width > this.minX + this.width)) { - throw new RasterFormatException("(x + width) is outside raster"); - } - if ((y+height < y) || (y+height > this.minY + this.height)) { - throw new RasterFormatException("(y + height) is outside raster"); - } - - SampleModel sm; - - if (bandList != null) - sm = sampleModel.createSubsetSampleModel(bandList); - else - sm = sampleModel; - - int deltaX = x0 - x; - int deltaY = y0 - y; - - return new IntegerComponentRaster(sm, - dataBuffer, - new Rectangle(x0,y0,width,height), - new Point(sampleModelTranslateX+deltaX, - sampleModelTranslateY+deltaY), - this); - } - - - /** - * Creates a subraster given a region of the raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this raster to the upper-left corner - * of the subraster. A subset of the bands of the parent raster may - * be specified. If this is null, then all the bands are present in the - * subRaster. Note that the subraster will reference the same - * DataBuffer as the parent raster, but using different offsets. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subRaster. - * @param y0 Translated Y origin of the subRaster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent raster. - */ - public Raster createChild (int x, int y, - int width, int height, - int x0, int y0, - int bandList[]) { - return createWritableChild(x, y, width, height, x0, y0, bandList); - } - - - /** - * Creates a raster with the same band layout but using a different - * width and height, and with new zeroed data arrays. - */ - public WritableRaster createCompatibleWritableRaster(int w, int h) { - if (w <= 0 || h <=0) { - throw new RasterFormatException("negative "+ - ((w <= 0) ? "width" : "height")); - } - - SampleModel sm = sampleModel.createCompatibleSampleModel(w,h); - - return new IntegerComponentRaster(sm, new Point(0,0)); - } - - /** - * Creates a raster with the same data layout and the same - * width and height, and with new zeroed data arrays. If - * the raster is a subraster, this will call - * createCompatibleRaster(width, height). - */ - public WritableRaster createCompatibleWritableRaster() { - return createCompatibleWritableRaster(width,height); - } - - /** - * Verify that the layout parameters are consistent with - * the data. If strictCheck - * is false, this method will check for ArrayIndexOutOfBounds conditions. If - * strictCheck is true, this method will check for additional error - * conditions such as line wraparound (width of a line greater than - * the scanline stride). - * @return String Error string, if the layout is incompatible with - * the data. Otherwise returns null. - */ - private void verify (boolean strictCheck) { - if (dataOffsets[0] < 0) { - throw new RasterFormatException("Data offset ("+dataOffsets[0]+ - ") must be >= 0"); - } - - int maxSize = 0; - int size; - - for (int i=0; i < numDataElements; i++) { - size = (height-1)*scanlineStride + (width-1)*pixelStride + - dataOffsets[i]; - if (size > maxSize) { - maxSize = size; - } - } - if (data.length < maxSize) { - throw new RasterFormatException("Data array too small (should be "+ - maxSize - +" but is "+data.length+" )"); - } - } - - public String toString() { - return new String ("IntegerComponentRaster: width = "+width - +" height = " + height - +" #Bands = " + numBands - +" #DataElements "+numDataElements - +" xOff = "+sampleModelTranslateX - +" yOff = "+sampleModelTranslateY - +" dataOffset[0] "+dataOffsets[0]); - } - -// /** -// * For debugging... prints a region of a one-band IntegerComponentRaster -// */ -// public void print(int x, int y, int w, int h) { -// // REMIND: Only works for 1 band! -// System.out.println(this); -// int offset = dataOffsets[0] + y*scanlineStride + x*pixelStride; -// int off; -// for (int yoff=0; yoff < h; yoff++, offset += scanlineStride) { -// off = offset; -// System.out.print("Line "+(sampleModelTranslateY+y+yoff)+": "); -// for (int xoff = 0; xoff < w; xoff++, off+= pixelStride) { -// System.out.print(Integer.toHexString(data[off])+" "); -// } -// System.out.println(""); -// } -// } - -} diff --git a/external/ikvm/openjdk/sun/awt/image/OffScreenImageSource.java b/external/ikvm/openjdk/sun/awt/image/OffScreenImageSource.java deleted file mode 100644 index 7e8e2dbc79..0000000000 --- a/external/ikvm/openjdk/sun/awt/image/OffScreenImageSource.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.awt.image; - -import java.util.Hashtable; -import java.awt.image.ImageConsumer; -import java.awt.image.ImageProducer; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.DirectColorModel; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; - -public class OffScreenImageSource implements ImageProducer { - BufferedImage image; - int width; - int height; - Hashtable properties; - - public OffScreenImageSource(BufferedImage image, - Hashtable properties) { - this.image = image; - if (properties != null) { - this.properties = properties; - } else { - this.properties = new Hashtable(); - } - width = image.getWidth(); - height = image.getHeight(); - } - - public OffScreenImageSource(BufferedImage image) { - this(image, null); - } - - // We can only have one consumer since we immediately return the data... - private ImageConsumer theConsumer; - - public synchronized void addConsumer(ImageConsumer ic) { - theConsumer = ic; - produce(); - } - - public synchronized boolean isConsumer(ImageConsumer ic) { - return (ic == theConsumer); - } - - public synchronized void removeConsumer(ImageConsumer ic) { - if (theConsumer == ic) { - theConsumer = null; - } - } - - public void startProduction(ImageConsumer ic) { - addConsumer(ic); - } - - public void requestTopDownLeftRightResend(ImageConsumer ic) { - } - - private void sendPixels() { - ColorModel cm = image.getColorModel(); - WritableRaster raster = image.getRaster(); - int numDataElements = raster.getNumDataElements(); - int dataType = raster.getDataBuffer().getDataType(); - int[] scanline = new int[width*numDataElements]; - boolean needToCvt = true; - - if (cm instanceof IndexColorModel) { - byte[] pixels = new byte[width]; - theConsumer.setColorModel(cm); - - if (raster instanceof ByteComponentRaster) { - needToCvt = false; - for (int y=0; y < height; y++) { - raster.getDataElements(0, y, width, 1, pixels); - theConsumer.setPixels(0, y, width, 1, cm, pixels, 0, - width); - } - } - else if (raster instanceof BytePackedRaster) { - needToCvt = false; - // Binary image. Need to unpack it - for (int y=0; y < height; y++) { - raster.getPixels(0, y, width, 1, scanline); - for (int x=0; x < width; x++) { - pixels[x] = (byte) scanline[x]; - } - theConsumer.setPixels(0, y, width, 1, cm, pixels, 0, - width); - } - } - else if (dataType == DataBuffer.TYPE_SHORT || - dataType == DataBuffer.TYPE_INT) - { - // Probably a short or int "GRAY" image - needToCvt = false; - for (int y=0; y < height; y++) { - raster.getPixels(0, y, width, 1, scanline); - theConsumer.setPixels(0, y, width, 1, cm, scanline, 0, - width); - } - } - } - else if (cm instanceof DirectColorModel) { - theConsumer.setColorModel(cm); - needToCvt = false; - switch (dataType) { - case DataBuffer.TYPE_INT: - for (int y=0; y < height; y++) { - raster.getDataElements(0, y, width, 1, scanline); - theConsumer.setPixels(0, y, width, 1, cm, scanline, 0, - width); - } - break; - case DataBuffer.TYPE_BYTE: - byte[] bscanline = new byte[width]; - for (int y=0; y < height; y++) { - raster.getDataElements(0, y, width, 1, bscanline); - for (int x=0; x < width; x++) { - scanline[x] = bscanline[x]&0xff; - } - theConsumer.setPixels(0, y, width, 1, cm, scanline, 0, - width); - } - break; - case DataBuffer.TYPE_USHORT: - short[] sscanline = new short[width]; - for (int y=0; y < height; y++) { - raster.getDataElements(0, y, width, 1, sscanline); - for (int x=0; x < width; x++) { - scanline[x] = sscanline[x]&0xffff; - } - theConsumer.setPixels(0, y, width, 1, cm, scanline, 0, - width); - } - break; - default: - needToCvt = true; - } - } - - if (needToCvt) { - // REMIND: Need to add other types of CMs here - ColorModel newcm = ColorModel.getRGBdefault(); - theConsumer.setColorModel(newcm); - - for (int y=0; y < height; y++) { - for (int x=0; x < width; x++) { - scanline[x] = image.getRGB(x, y); - } - theConsumer.setPixels(0, y, width, 1, newcm, scanline, 0, - width); - } - } - } - - private void produce() { - try { - theConsumer.setDimensions(image.getWidth(), image.getHeight()); - theConsumer.setProperties(properties); - sendPixels(); - theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE); - } catch (NullPointerException e) { - if (theConsumer != null) { - theConsumer.imageComplete(ImageConsumer.IMAGEERROR); - } - } - } -} diff --git a/external/ikvm/openjdk/sun/awt/image/ShortComponentRaster.java b/external/ikvm/openjdk/sun/awt/image/ShortComponentRaster.java deleted file mode 100644 index f353fa8c8a..0000000000 --- a/external/ikvm/openjdk/sun/awt/image/ShortComponentRaster.java +++ /dev/null @@ -1,829 +0,0 @@ -/* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.awt.image; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.awt.image.RasterFormatException; -import java.awt.image.SampleModel; -import java.awt.image.ComponentSampleModel; -import java.awt.image.SinglePixelPackedSampleModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferUShort; -import java.awt.Rectangle; -import java.awt.Point; - -/** - * This class defines a Raster with pixels consisting of one or more 16-bit - * data elements stored in close proximity to each other in a short integer - * array. The bit precision per data element is that - * of the data type (that is, the bit precision for this Raster is 16). - * There is only one pixel stride and one scanline stride for all - * bands. This type of Raster can be used with a - * ComponentColorModel if there are multiple bands, or a - * IndexColorModel if there is only one band. - * <p> - * For example, 5-6-5 RGB image data can be represented by a - * ShortComponentRaster using a SinglePixelPackedSampleModel and - * a ComponentColorModel. - * - * - */ -public class ShortComponentRaster extends SunWritableRaster { - - /** private band offset for use by native code */ - protected int bandOffset; - - /** Data offsets for each band of image data. */ - protected int[] dataOffsets; - - /** Scanline stride of the image data contained in this Raster. */ - protected int scanlineStride; - - /** Pixel stride of the image data contained in this Raster. */ - protected int pixelStride; - - /** The image data array. */ - protected short[] data; - - int type; - - /** A cached copy of minX + width for use in bounds checks. */ - private int maxX; - - /** A cached copy of minY + height for use in bounds checks. */ - private int maxY; - - /** - * Constructs a ShortComponentRaster with the given SampleModel. - * The Raster's upper left corner is origin and it is the same - * size as the SampleModel. A DataBuffer large enough to describe the - * Raster is automatically created. SampleModel must be of type - * ComponentSampleModel or SinglePixelPackedSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param origin The Point that specified the origin. - */ - public ShortComponentRaster(SampleModel sampleModel, Point origin) { - this(sampleModel, - sampleModel.createDataBuffer(), - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a ShortComponentRaster with the given SampleModel - * and DataBuffer. The Raster's upper left corner is origin and - * it is the same sizes the SampleModel. The DataBuffer is not - * initialized and must be a DataBufferUShort compatible with SampleModel. - * SampleModel must be of type ComponentSampleModel or - * SinglePixelPackedSampleModel. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferUShort that contains the image data. - * @param origin The Point that specifies the origin. - */ - public ShortComponentRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Point origin) { - this(sampleModel, - dataBuffer, - new Rectangle(origin.x, - origin.y, - sampleModel.getWidth(), - sampleModel.getHeight()), - origin, - null); - } - - /** - * Constructs a ShortComponentRaster with the given SampleModel, - * DataBuffer, and parent. DataBuffer must be a DataBufferUShort and - * SampleModel must be of type ComponentSampleModel or - * SinglePixelPackedSampleModel. When translated into the base Raster's - * coordinate system, aRegion must be contained by the base Raster. - * Origin is the coodinate in the new Raster's coordinate system of - * the origin of the base Raster. (The base Raster is the Raster's - * ancestor which has no parent.) - * - * Note that this constructor should generally be called by other - * constructors or create methods, it should not be used directly. - * @param sampleModel The SampleModel that specifies the layout. - * @param dataBuffer The DataBufferUShort that contains the image data. - * @param aRegion The Rectangle that specifies the image area. - * @param origin The Point that specifies the origin. - * @param parent The parent (if any) of this raster. - */ - public ShortComponentRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Rectangle aRegion, - Point origin, - ShortComponentRaster parent) { - - super(sampleModel, dataBuffer, aRegion, origin, parent); - this.maxX = minX + width; - this.maxY = minY + height; - - if(!(dataBuffer instanceof DataBufferUShort)) { - throw new RasterFormatException("ShortComponentRasters must have "+ - "short DataBuffers"); - } - - DataBufferUShort dbus = (DataBufferUShort)dataBuffer; - this.data = stealData(dbus, 0); - if (dbus.getNumBanks() != 1) { - throw new - RasterFormatException("DataBuffer for ShortComponentRasters"+ - " must only have 1 bank."); - } - int dbOffset = dbus.getOffset(); - - if (sampleModel instanceof ComponentSampleModel) { - ComponentSampleModel csm = (ComponentSampleModel)sampleModel; - this.type = IntegerComponentRaster.TYPE_USHORT_SAMPLES; - this.scanlineStride = csm.getScanlineStride(); - this.pixelStride = csm.getPixelStride(); - this.dataOffsets = csm.getBandOffsets(); - int xOffset = aRegion.x - origin.x; - int yOffset = aRegion.y - origin.y; - for (int i = 0; i < getNumDataElements(); i++) { - dataOffsets[i] += dbOffset + - xOffset*pixelStride+yOffset*scanlineStride; - } - } else if (sampleModel instanceof SinglePixelPackedSampleModel) { - SinglePixelPackedSampleModel sppsm = - (SinglePixelPackedSampleModel)sampleModel; - this.type = IntegerComponentRaster.TYPE_USHORT_PACKED_SAMPLES; - this.scanlineStride = sppsm.getScanlineStride(); - this.pixelStride = 1; - this.dataOffsets = new int[1]; - this.dataOffsets[0] = dbOffset; - int xOffset = aRegion.x - origin.x; - int yOffset = aRegion.y - origin.y; - dataOffsets[0] += xOffset+yOffset*scanlineStride; - } else { - throw new RasterFormatException("ShortComponentRasters must have"+ - "ComponentSampleModel or SinglePixelPackedSampleModel"); - } - this.bandOffset = this.dataOffsets[0]; - - verify(false); - } - - /** - * Returns a copy of the data offsets array. For each band the data offset - * is the index into the band's data array, of the first sample of the - * band. - */ - public int[] getDataOffsets() { - return (int[]) dataOffsets.clone(); - } - - /** - * Returns the data offset for the specified band. The data offset - * is the index into the data array in which the first sample - * of the first scanline is stored. - * @param band The band whose offset is returned. - */ - public int getDataOffset(int band) { - return dataOffsets[band]; - } - - /** - * Returns the scanline stride -- the number of data array elements between - * a given sample and the same sample in the same column of the next row. - */ - public int getScanlineStride() { - return scanlineStride; - } - - /** - * Returns pixel stride -- the number of data array elements between two - * samples for the same band on the same scanline. - */ - public int getPixelStride() { - return pixelStride; - } - - /** - * Returns a reference to the data array. - */ - public short[] getDataStorage() { - return data; - } - - /** - * Returns the data elements for all bands at the specified - * location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param outData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - short outData[]; - if (obj == null) { - outData = new short[numDataElements]; - } else { - outData = (short[])obj; - } - int off = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - - for (int band = 0; band < numDataElements; band++) { - outData[band] = data[dataOffsets[band] + off]; - } - - return outData; - } - - /** - * Returns an array of data elements from the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * <pre> - * short[] bandData = (short[])Raster.getDataElements(x, y, w, h, null); - * int numDataElements = Raster.getBands(); - * short[] pixel = new short[numDataElements]; - * // To find the data element at location (x2, y2) - * System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements, - * pixel, 0, numDataElements); - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param outData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements(). - * If null an array of appropriate type and size will be - * allocated. - * @return An object reference to an array of type defined by - * getTransferType() with the request pixel data. - */ - public Object getDataElements(int x, int y, int w, int h, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - short outData[]; - if (obj == null) { - outData = new short[w*h*numDataElements]; - } else { - outData = (short[])obj; - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - - int xoff; - int off = 0; - int xstart; - int ystart; - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - outData[off++] = data[dataOffsets[c] + xoff]; - } - } - } - - return outData; - } - - /** - * Returns a short integer array of data elements from the - * specified rectangular region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * <pre> - * short[] bandData = Raster.getShortData(x, y, w, h, null); - * // To find the data element at location (x2, y2) - * short dataElenent = bandData[((y2-y)*w + (x2-x))]; - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the sample rectangle. - * @param height Height of the sample rectangle. - * @param band The band to return. - * @param outData If non-null, data elements for all bands - * at the specified location are returned in this array. - * @return Data array with data elements for all bands. - */ - public short[] getShortData(int x, int y, int w, int h, - int band, short[] outData) { - // Bounds check for 'band' will be performed automatically - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - if (outData == null) { - outData = new short[numDataElements*w*h]; - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride+ dataOffsets[band]; - int xoff; - int off = 0; - int xstart; - int ystart; - - if (pixelStride == 1) { - if (scanlineStride == w) { - System.arraycopy(data, yoff, outData, 0, w*h); - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - System.arraycopy(data, yoff, outData, off, w); - off += w; - } - } - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - outData[off++] = data[xoff]; - } - } - } - - return outData; - } - - /** - * Returns a short integer array of data elements from the - * specified rectangular region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * <pre> - * short[] bandData = Raster.getShortData(x, y, w, h, null); - * int numDataElements = Raster.getNumBands(); - * short[] pixel = new short[numDataElements]; - * // To find the data element at location (x2, y2) - * System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements, - * pixel, 0, numDataElements); - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param width Width of the pixel rectangle. - * @param height Height of the pixel rectangle. - * @param outData If non-null, data elements for all bands - * at the specified location are returned in this array. - * @return Data array with data elements for all bands. - */ - public short[] getShortData(int x, int y, int w, int h, short[] outData) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - if (outData == null) { - outData = new short[numDataElements*w*h]; - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - outData[off++] = data[dataOffsets[c] + xoff]; - } - } - } - - return outData; - } - - /** - * Stores the data elements for all bands at the specified location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinate is out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inData An object reference to an array of type defined by - * getTransferType() and length getNumDataElements() - * containing the pixel data to place at x,y. - */ - public void setDataElements(int x, int y, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x >= this.maxX) || (y >= this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - short inData[] = (short[])obj; - int off = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - for (int i = 0; i < numDataElements; i++) { - data[dataOffsets[i] + off] = (short) inData[i]; - } - - markDirty(); - } - - /** - * Stores the Raster data at the specified location. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * @param x The X coordinate of the pixel location. - * @param y The Y coordinate of the pixel location. - * @param inRaster Raster of data to place at x,y location. - */ - public void setDataElements(int x, int y, Raster inRaster) { - int dstOffX = x + inRaster.getMinX(); - int dstOffY = y + inRaster.getMinY(); - int width = inRaster.getWidth(); - int height = inRaster.getHeight(); - if ((dstOffX < this.minX) || (dstOffY < this.minY) || - (dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - - setDataElements(dstOffX, dstOffY, width, height, inRaster); - } - - /** - * Stores the Raster data at the specified location. - * @param dstX The absolute X coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param dstY The absolute Y coordinate of the destination pixel - * that will receive a copy of the upper-left pixel of the - * inRaster - * @param width The number of pixels to store horizontally - * @param height The number of pixels to store vertically - * @param inRaster Raster of data to place at x,y location. - */ - private void setDataElements(int dstX, int dstY, - int width, int height, - Raster inRaster) { - // Assume bounds checking has been performed previously - if (width <= 0 || height <= 0) { - return; - } - - // Write inRaster (minX, minY) to (dstX, dstY) - - int srcOffX = inRaster.getMinX(); - int srcOffY = inRaster.getMinY(); - Object tdata = null; - -// // REMIND: Do something faster! -// if (inRaster instanceof ShortComponentRaster) { -// } - - for (int startY=0; startY < height; startY++) { - // Grab one scanline at a time - tdata = inRaster.getDataElements(srcOffX, srcOffY+startY, - width, 1, tdata); - setDataElements(dstX, dstY + startY, width, 1, tdata); - } - } - - /** - * Stores an array of data elements into the specified rectangular - * region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * A ClassCastException will be thrown if the input object is non null - * and references anything other than an array of transferType. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * for the nth band at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))*numDataElements + n] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param inData An object reference to an array of type defined by - * getTransferType() and length w*h*getNumDataElements() - * containing the pixel data to place between x,y and - * x+h, y+h. - */ - public void setDataElements(int x, int y, int w, int h, Object obj) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - short inData[] = (short[])obj; - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - data[dataOffsets[c] + xoff] = (short) inData[off++]; - } - } - } - - markDirty(); - } - - /** - * Stores a short integer array of data elements into the - * specified rectangular region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param band The band to set. - * @param inData The data elements to be stored. - */ - public void putShortData(int x, int y, int w, int h, - int band, short[] inData) { - // Bounds check for 'band' will be performed automatically - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride + dataOffsets[band]; - int xoff; - int off = 0; - int xstart; - int ystart; - - if (pixelStride == 1) { - if (scanlineStride == w) { - System.arraycopy(inData, 0, data, yoff, w*h); - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - System.arraycopy(inData, off, data, yoff, w); - off += w; - } - } - } - else { - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - data[xoff] = inData[off++]; - } - } - } - - markDirty(); - } - - /** - * Stores a short integer array of data elements into the - * specified rectangular region. - * An ArrayIndexOutOfBounds exception will be thrown at runtime - * if the pixel coordinates are out of bounds. - * The data elements in the - * data array are assumed to be packed. That is, a data element - * for the nth band at location (x2, y2) would be found at: - * <pre> - * inData[((y2-y)*w + (x2-x))*numDataElements + n] - * </pre> - * @param x The X coordinate of the upper left pixel location. - * @param y The Y coordinate of the upper left pixel location. - * @param w Width of the pixel rectangle. - * @param h Height of the pixel rectangle. - * @param inData The data elements to be stored. - */ - public void putShortData(int x, int y, int w, int h, short[] inData) { - if ((x < this.minX) || (y < this.minY) || - (x + w > this.maxX) || (y + h > this.maxY)) { - throw new ArrayIndexOutOfBoundsException - ("Coordinate out of bounds!"); - } - int yoff = (y-minY)*scanlineStride + - (x-minX)*pixelStride; - int xoff; - int off = 0; - int xstart; - int ystart; - - for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) { - xoff = yoff; - for (xstart=0; xstart < w; xstart++, xoff += pixelStride) { - for (int c = 0; c < numDataElements; c++) { - data[dataOffsets[c] + xoff] = inData[off++]; - } - } - } - - markDirty(); - } - - /** - * Creates a subraster given a region of the raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this raster to the upper-left corner - * of the subraster. A subset of the bands of the parent Raster may - * be specified. If this is null, then all the bands are present in the - * subRaster. A translation to the subRaster may also be specified. - * Note that the subraster will reference the same - * band objects as the parent raster, but using different offsets. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subraster. - * @param y0 Translated Y origin of the subraster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent raster. - */ - public Raster createChild (int x, int y, - int width, int height, - int x0, int y0, int[] bandList) { - WritableRaster newRaster = createWritableChild(x, y, - width, height, - x0, y0, - bandList); - return (Raster) newRaster; - } - - /** - * Creates a Writable subRaster given a region of the Raster. The x and y - * coordinates specify the horizontal and vertical offsets - * from the upper-left corner of this Raster to the upper-left corner - * of the subRaster. A subset of the bands of the parent Raster may - * be specified. If this is null, then all the bands are present in the - * subRaster. A translation to the subRaster may also be specified. - * Note that the subRaster will reference the same - * DataBuffers as the parent Raster, but using different offsets. - * @param x X offset. - * @param y Y offset. - * @param width Width (in pixels) of the subraster. - * @param height Height (in pixels) of the subraster. - * @param x0 Translated X origin of the subraster. - * @param y0 Translated Y origin of the subraster. - * @param bandList Array of band indices. - * @exception RasterFormatException - * if the specified bounding box is outside of the parent Raster. - */ - public WritableRaster createWritableChild(int x, int y, - int width, int height, - int x0, int y0, - int[] bandList) { - if (x < this.minX) { - throw new RasterFormatException("x lies outside the raster"); - } - if (y < this.minY) { - throw new RasterFormatException("y lies outside the raster"); - } - if ((x+width < x) || (x+width > this.minX + this.width)) { - throw new RasterFormatException("(x + width) is outside of Raster"); - } - if ((y+height < y) || (y+height > this.minY + this.height)) { - throw new RasterFormatException("(y + height) is outside of Raster"); - } - - SampleModel sm; - - if (bandList != null) - sm = sampleModel.createSubsetSampleModel(bandList); - else - sm = sampleModel; - - int deltaX = x0 - x; - int deltaY = y0 - y; - - return new ShortComponentRaster(sm, - dataBuffer, - new Rectangle(x0, y0, width, height), - new Point(sampleModelTranslateX+deltaX, - sampleModelTranslateY+deltaY), - this); - } - - /** - * Creates a Raster with the same layout but using a different - * width and height, and with new zeroed data arrays. - */ - public WritableRaster createCompatibleWritableRaster(int w, int h) { - if (w <= 0 || h <=0) { - throw new RasterFormatException("negative "+ - ((w <= 0) ? "width" : "height")); - } - - SampleModel sm = sampleModel.createCompatibleSampleModel(w, h); - - return new ShortComponentRaster(sm, new Point(0, 0)); - } - - /** - * Creates a Raster with the same layout and the same - * width and height, and with new zeroed data arrays. If - * the Raster is a subRaster, this will call - * createCompatibleRaster(width, height). - */ - public WritableRaster createCompatibleWritableRaster() { - return createCompatibleWritableRaster(width,height); - } - - /** - * Verify that the layout parameters are consistent with - * the data. If strictCheck - * is false, this method will check for ArrayIndexOutOfBounds conditions. If - * strictCheck is true, this method will check for additional error - * conditions such as line wraparound (width of a line greater than - * the scanline stride). - * @return String Error string, if the layout is incompatible with - * the data. Otherwise returns null. - */ - private void verify (boolean strictCheck) { - // Make sure data for Raster is in a legal range - for (int i=0; i < dataOffsets.length; i++) { - if (dataOffsets[i] < 0) { - throw new RasterFormatException("Data offsets for band "+i+ - "("+dataOffsets[i]+ - ") must be >= 0"); - } - } - - int maxSize = 0; - int size; - - for (int i=0; i < numDataElements; i++) { - size = (height-1)*scanlineStride + (width-1)*pixelStride + - dataOffsets[i]; - if (size > maxSize) { - maxSize = size; - } - } - if (data.length < maxSize) { - throw new RasterFormatException("Data array too small (should be "+ - maxSize+" )"); - } - } - - public String toString() { - return new String ("ShortComponentRaster: width = "+width - +" height = " + height - +" #numDataElements "+numDataElements); - // +" xOff = "+xOffset+" yOff = "+yOffset); - } - -} diff --git a/external/ikvm/openjdk/sun/font/StandardGlyphVector.java b/external/ikvm/openjdk/sun/font/StandardGlyphVector.java index aec6572efb..fb3de314fa 100644 --- a/external/ikvm/openjdk/sun/font/StandardGlyphVector.java +++ b/external/ikvm/openjdk/sun/font/StandardGlyphVector.java @@ -94,8 +94,21 @@ public class StandardGlyphVector extends GlyphVector{ this(font, getString(iter), frc); } - public StandardGlyphVector(Font font, int[] glyphs, FontRenderContext frc) { - throw new NotYetImplementedError(); + public StandardGlyphVector( Font font, int[] glyphs, FontRenderContext frc ) { + this( font, glyphs2chars(glyphs), frc ); + } + + /** + * Symmetric to {@link #getGlyphCodes(int, int, int[])} + * Currently there is no real mapping possible between the chars and the glyph IDs in the TTF file + */ + private static char[] glyphs2chars( int[] glyphs ) { + int count = glyphs.length; + char[] text = new char[count]; + for( int i = 0; i < count; ++i ) { + text[i] = (char)glyphs[i]; + } + return text; } ///////////////////////////// diff --git a/external/ikvm/openjdk/sun/misc/IoTrace.java b/external/ikvm/openjdk/sun/misc/IoTrace.java new file mode 100644 index 0000000000..ab15ed160a --- /dev/null +++ b/external/ikvm/openjdk/sun/misc/IoTrace.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +import java.net.InetAddress; + +/** + * Utility class used to identify trace points for I/O calls. + * <p> + * To use this class, a diagnostic tool must redefine this class with a version + * that contains calls to the the diagnostic tool. This implementation will then + * receive callbacks when file and socket operations are performed. The reason + * for requiring a redefine of the class is to avoid any overhead caused by the + * instrumentation. + * <p> + * The xxBegin() methods return a "context". This can be any Object. This + * context will be passed to the corresponding xxEnd() method. This way, an + * implementation can correlate the beginning of an operation with the end. + * <p> + * It is possible for a xxEnd() method to be called with a null handle. This + * happens if tracing was started between the call to xxBegin() and xxEnd(), in + * which case xxBegin() would not have been called. It is the implementation's + * responsibility to not throw an exception in this case. + * <p> + * Only blocking I/O operations are identified with this facility. + * <p> + * <b>Warning</b> + * <p> + * These methods are called from sensitive points in the I/O subsystem. Great + * care must be taken to not interfere with ongoing operations or cause + * deadlocks. In particular: + * <ul> + * <li>Implementations must not throw exceptions since this will cause + * disruptions to the I/O operations. + * <li>Implementations must not do I/O operations since this will lead to an + * endless loop. + * <li>Since the hooks may be called while holding low-level locks in the I/O + * subsystem, implementations must be careful with synchronization or + * interaction with other threads to avoid deadlocks in the VM. + * </ul> + */ +public final class IoTrace { + private IoTrace() { + } + + /** + * Called before data is read from a socket. + * + * @return a context object + */ + public static Object socketReadBegin() { + return null; + } + + /** + * Called after data is read from the socket. + * + * @param context + * the context returned by the previous call to socketReadBegin() + * @param address + * the remote address the socket is bound to + * @param port + * the remote port the socket is bound to + * @param timeout + * the SO_TIMEOUT value of the socket (in milliseconds) or 0 if + * there is no timeout set + * @param bytesRead + * the number of bytes read from the socket, 0 if there was an + * error reading from the socket + */ + public static void socketReadEnd(Object context, InetAddress address, int port, + int timeout, long bytesRead) { + } + + /** + * Called before data is written to a socket. + * + * @return a context object + */ + public static Object socketWriteBegin() { + return null; + } + + /** + * Called after data is written to a socket. + * + * @param context + * the context returned by the previous call to + * socketWriteBegin() + * @param address + * the remote address the socket is bound to + * @param port + * the remote port the socket is bound to + * @param bytesWritten + * the number of bytes written to the socket, 0 if there was an + * error writing to the socket + */ + public static void socketWriteEnd(Object context, InetAddress address, int port, + long bytesWritten) { + } + + /** + * Called before data is read from a file. + * + * @param path + * the path of the file + * @return a context object + */ + public static Object fileReadBegin(String path) { + return null; + } + + /** + * Called after data is read from a file. + * + * @param context + * the context returned by the previous call to fileReadBegin() + * @param bytesRead + * the number of bytes written to the file, 0 if there was an + * error writing to the file + */ + public static void fileReadEnd(Object context, long bytesRead) { + } + + /** + * Called before data is written to a file. + * + * @param path + * the path of the file + * @return a context object + */ + public static Object fileWriteBegin(String path) { + return null; + } + + /** + * Called after data is written to a file. + * + * @param context + * the context returned by the previous call to fileReadBegin() + * @param bytesWritten + * the number of bytes written to the file, 0 if there was an + * error writing to the file + */ + public static void fileWriteEnd(Object context, long bytesWritten) { + } +} diff --git a/external/ikvm/openjdk/sun/misc/JavaAWTAccess.java b/external/ikvm/openjdk/sun/misc/JavaAWTAccess.java new file mode 100644 index 0000000000..462eb9ab86 --- /dev/null +++ b/external/ikvm/openjdk/sun/misc/JavaAWTAccess.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +public interface JavaAWTAccess { + public Object getContext(); + public Object getExecutionContext(); + + public Object get(Object context, Object key); + public void put(Object context, Object key, Object value); + public void remove(Object context, Object key); + + // convenience methods whose context is the object returned by getContext() + public Object get(Object key); + public void put(Object key, Object value); + public void remove(Object key); + public boolean isDisposed(); + public boolean isMainAppContext(); +} diff --git a/external/ikvm/openjdk/sun/misc/SharedSecrets.java b/external/ikvm/openjdk/sun/misc/SharedSecrets.java index af2174c992..172c4c588e 100644 --- a/external/ikvm/openjdk/sun/misc/SharedSecrets.java +++ b/external/ikvm/openjdk/sun/misc/SharedSecrets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,6 +52,7 @@ public class SharedSecrets { private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess; private static JavaSecurityAccess javaSecurityAccess; private static JavaxSecurityAuthKerberosAccess javaxSecurityAuthKerberosAccess; + private static JavaAWTAccess javaAWTAccess; public static JavaUtilJarAccess javaUtilJarAccess() { if (javaUtilJarAccess == null) { @@ -146,4 +147,17 @@ public class SharedSecrets { unsafe.ensureClassInitialized(KeyTab.class); return javaxSecurityAuthKerberosAccess; } + + public static void setJavaAWTAccess(JavaAWTAccess jaa) { + javaAWTAccess = jaa; + } + + public static JavaAWTAccess getJavaAWTAccess() { + // this may return null in which case calling code needs to + // provision for. + if (javaAWTAccess == null || javaAWTAccess.getContext() == null) { + return null; + } + return javaAWTAccess; + } } diff --git a/external/ikvm/openjdk/sun/misc/Unsafe.java b/external/ikvm/openjdk/sun/misc/Unsafe.java index 104b4c0d36..748e3b0240 100644 --- a/external/ikvm/openjdk/sun/misc/Unsafe.java +++ b/external/ikvm/openjdk/sun/misc/Unsafe.java @@ -46,7 +46,7 @@ public final class Unsafe private Unsafe() { } - @ikvm.internal.HasCallerID + @sun.reflect.CallerSensitive public static Unsafe getUnsafe() { if(ikvm.internal.CallerID.getCallerID().getCallerClassLoader() != null) diff --git a/external/ikvm/openjdk/sun/nio/ch/DatagramChannelImpl.java b/external/ikvm/openjdk/sun/nio/ch/DatagramChannelImpl.java index b263153007..08cc5c95d0 100644 --- a/external/ikvm/openjdk/sun/nio/ch/DatagramChannelImpl.java +++ b/external/ikvm/openjdk/sun/nio/ch/DatagramChannelImpl.java @@ -86,8 +86,8 @@ class DatagramChannelImpl private int state = ST_UNINITIALIZED; // Binding - private SocketAddress localAddress; - private SocketAddress remoteAddress; + private InetSocketAddress localAddress; + private InetSocketAddress remoteAddress; // Our socket adaptor, if any private DatagramSocket socket; @@ -95,6 +95,12 @@ class DatagramChannelImpl // Multicast support private MembershipRegistry registry; + // set true when socket is bound and SO_REUSEADDRESS is emulated + private boolean reuseAddressEmulated; + + // set true/false when socket is already bound and SO_REUSEADDR is emulated + private boolean isReuseAddress; + // -- End of fields protected by stateLock @@ -163,7 +169,7 @@ class DatagramChannelImpl synchronized (stateLock) { if (!isOpen()) throw new ClosedChannelException(); - return localAddress; + return Net.getRevealedLocalAddress(localAddress); } } @@ -223,6 +229,12 @@ class DatagramChannelImpl } return this; } + if (name == StandardSocketOptions.SO_REUSEADDR && + Net.useExclusiveBind() && localAddress != null) + { + reuseAddressEmulated = true; + this.isReuseAddress = (Boolean)value; + } // remaining options don't need any special handling Net.setSocketOption(fd, Net.UNSPEC, name, value); @@ -281,6 +293,12 @@ class DatagramChannelImpl } } + if (name == StandardSocketOptions.SO_REUSEADDR && + reuseAddressEmulated) + { + return (T)Boolean.valueOf(isReuseAddress); + } + // no special handling return (T) Net.getSocketOption(fd, Net.UNSPEC, name); } @@ -416,7 +434,7 @@ class DatagramChannelImpl synchronized (writeLock) { ensureOpen(); - InetSocketAddress isa = (InetSocketAddress)target; + InetSocketAddress isa = Net.checkAddress(target); InetAddress ia = isa.getAddress(); if (ia == null) throw new IOException("Target address not resolved"); @@ -427,9 +445,9 @@ class DatagramChannelImpl SecurityManager sm = System.getSecurityManager(); if (sm != null) { if (ia.isMulticastAddress()) { - sm.checkMulticast(isa.getAddress()); + sm.checkMulticast(ia); } else { - sm.checkConnect(isa.getAddress().getHostAddress(), + sm.checkConnect(ia.getHostAddress(), isa.getPort()); } } @@ -449,7 +467,7 @@ class DatagramChannelImpl return 0; writerThread = NativeThread.current(); do { - n = send(fd, src, target); + n = send(fd, src, isa); } while ((n == IOStatus.INTERRUPTED) && isOpen()); synchronized (stateLock) { @@ -466,7 +484,7 @@ class DatagramChannelImpl } } - private int send(FileDescriptor fd, ByteBuffer src, SocketAddress target) + private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target) throws IOException { if (src.hasArray()) @@ -496,7 +514,7 @@ class DatagramChannelImpl } private int sendFromManagedBuffer(FileDescriptor fd, ByteBuffer bb, - SocketAddress target) + InetSocketAddress target) throws IOException { int pos = bb.position(); @@ -508,7 +526,7 @@ class DatagramChannelImpl int written; try { written = send0(preferIPv6, fd, bb.array(), bb.arrayOffset() + pos, - rem, target); + rem, target.getAddress(), target.getPort()); } catch (PortUnreachableException pue) { if (isConnected()) throw pue; @@ -700,6 +718,7 @@ class DatagramChannelImpl } } + @Override public DatagramChannel connect(SocketAddress sa) throws IOException { int localPort = 0; @@ -721,7 +740,7 @@ class DatagramChannelImpl // Connection succeeded; disallow further invocation state = ST_CONNECTED; - remoteAddress = sa; + remoteAddress = isa; sender = isa; cachedSenderInetAddress = isa.getAddress(); cachedSenderPort = isa.getPort(); @@ -740,12 +759,13 @@ class DatagramChannelImpl synchronized (stateLock) { if (!isConnected() || !isOpen()) return this; - InetSocketAddress isa = (InetSocketAddress)remoteAddress; + InetSocketAddress isa = remoteAddress; SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort()); - disconnect0(fd); + boolean isIPv6 = (family == StandardProtocolFamily.INET6); + disconnect0(fd, isIPv6); remoteAddress = null; state = ST_UNCONNECTED; @@ -1074,15 +1094,15 @@ class DatagramChannelImpl private static native void initIDs(); - private static native void disconnect0(FileDescriptor fd) + private static native void disconnect0(FileDescriptor fd, boolean isIPv6) throws IOException; private native int receive0(FileDescriptor fd, byte[] buf, int pos, int len, boolean connected) throws IOException; - private native int send0(boolean preferIPv6, FileDescriptor fd, byte[] buf, int pos, int len, - SocketAddress sa) + private native int send0(boolean preferIPv6, FileDescriptor fd, byte[] buf, int pos, + int len, InetAddress addr, int port) throws IOException; static { diff --git a/external/ikvm/openjdk/sun/nio/ch/FileChannelImpl.java b/external/ikvm/openjdk/sun/nio/ch/FileChannelImpl.java index 160e1f54e9..902509bdb6 100644 --- a/external/ikvm/openjdk/sun/nio/ch/FileChannelImpl.java +++ b/external/ikvm/openjdk/sun/nio/ch/FileChannelImpl.java @@ -29,8 +29,6 @@ import cli.Microsoft.Win32.SafeHandles.SafeFileHandle; import cli.System.IntPtr; import cli.System.IO.FileStream; import cli.System.Runtime.InteropServices.DllImportAttribute; -import cli.System.Runtime.InteropServices.StructLayoutAttribute; -import cli.System.Runtime.InteropServices.LayoutKind; import java.io.FileDescriptor; import java.io.IOException; import java.nio.ByteBuffer; @@ -40,6 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.security.AccessController; import sun.misc.Cleaner; +import sun.misc.IoTrace; import sun.security.action.GetPropertyAction; public class FileChannelImpl @@ -64,13 +63,16 @@ public class FileChannelImpl // Required to prevent finalization of creating stream (immutable) private final Object parent; + // The path of the referenced file (null if the parent stream is created with a file descriptor) + private final String path; + // Thread-safe set of IDs of native threads, for signalling private final NativeThreadSet threads = new NativeThreadSet(2); // Lock for operations involving position and size private final Object positionLock = new Object(); - private FileChannelImpl(FileDescriptor fd, boolean readable, + private FileChannelImpl(FileDescriptor fd, String path, boolean readable, boolean writable, boolean append, Object parent) { this.fd = fd; @@ -78,23 +80,24 @@ public class FileChannelImpl this.writable = writable; this.append = append; this.parent = parent; + this.path = path; this.nd = new FileDispatcherImpl(append); } // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel() - public static FileChannel open(FileDescriptor fd, + public static FileChannel open(FileDescriptor fd, String path, boolean readable, boolean writable, Object parent) { - return new FileChannelImpl(fd, readable, writable, false, parent); + return new FileChannelImpl(fd, path, readable, writable, false, parent); } // Used by FileOutputStream.getChannel - public static FileChannel open(FileDescriptor fd, + public static FileChannel open(FileDescriptor fd, String path, boolean readable, boolean writable, boolean append, Object parent) { - return new FileChannelImpl(fd, readable, writable, append, parent); + return new FileChannelImpl(fd, path, readable, writable, append, parent); } private void ensureOpen() throws IOException { @@ -142,6 +145,7 @@ public class FileChannelImpl synchronized (positionLock) { int n = 0; int ti = -1; + Object traceContext = IoTrace.fileReadBegin(path); try { begin(); ti = threads.add(); @@ -153,6 +157,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -170,6 +175,7 @@ public class FileChannelImpl synchronized (positionLock) { long n = 0; int ti = -1; + Object traceContext = IoTrace.fileReadBegin(path); try { begin(); ti = threads.add(); @@ -181,6 +187,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -194,6 +201,7 @@ public class FileChannelImpl synchronized (positionLock) { int n = 0; int ti = -1; + Object traceContext = IoTrace.fileWriteBegin(path); try { begin(); ti = threads.add(); @@ -206,6 +214,7 @@ public class FileChannelImpl } finally { threads.remove(ti); end(n > 0); + IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0); assert IOStatus.check(n); } } @@ -222,6 +231,7 @@ public class FileChannelImpl synchronized (positionLock) { long n = 0; int ti = -1; + Object traceContext = IoTrace.fileWriteBegin(path); try { begin(); ti = threads.add(); @@ -233,6 +243,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -513,6 +524,7 @@ public class FileChannelImpl ensureOpen(); int n = 0; int ti = -1; + Object traceContext = IoTrace.fileReadBegin(path); try { begin(); ti = threads.add(); @@ -524,6 +536,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -539,6 +552,7 @@ public class FileChannelImpl ensureOpen(); int n = 0; int ti = -1; + Object traceContext = IoTrace.fileWriteBegin(path); try { begin(); ti = threads.add(); @@ -551,6 +565,7 @@ public class FileChannelImpl } finally { threads.remove(ti); end(n > 0); + IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0); assert IOStatus.check(n); } } diff --git a/external/ikvm/openjdk/sun/nio/ch/Net.java b/external/ikvm/openjdk/sun/nio/ch/Net.java index 71ae543637..d9ab0f0fc7 100644 --- a/external/ikvm/openjdk/sun/nio/ch/Net.java +++ b/external/ikvm/openjdk/sun/nio/ch/Net.java @@ -31,6 +31,7 @@ import java.nio.channels.*; import java.util.*; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; class Net { // package-private @@ -44,6 +45,40 @@ class Net { // package-private } }; + // Value of jdk.net.revealLocalAddress + private static boolean revealLocalAddress; + + // True if jdk.net.revealLocalAddress had been read + private static volatile boolean propRevealLocalAddress; + + // set to true if exclusive binding is on for Windows + private static final boolean exclusiveBind; + + static { + int availLevel = isExclusiveBindAvailable(); + if (availLevel >= 0) { + String exclBindProp = + java.security.AccessController.doPrivileged( + new PrivilegedAction<String>() { + @Override + public String run() { + return System.getProperty( + "sun.net.useExclusiveBind"); + } + }); + if (exclBindProp != null) { + exclusiveBind = exclBindProp.length() == 0 ? + true : Boolean.parseBoolean(exclBindProp); + } else if (availLevel == 1) { + exclusiveBind = true; + } else { + exclusiveBind = false; + } + } else { + exclusiveBind = false; + } + } + // -- Miscellaneous utilities -- private static volatile boolean checkedIPv6 = false; @@ -61,6 +96,13 @@ class Net { // package-private } /** + * Returns true if exclusive binding is on + */ + static boolean useExclusiveBind() { + return exclusiveBind; + } + + /** * Tells whether IPv6 sockets can join IPv4 multicast groups */ static boolean canIPv6SocketJoinIPv4Group() { @@ -148,6 +190,58 @@ class Net { // package-private } /** + * Returns the local address after performing a SecurityManager#checkConnect. + */ + static InetSocketAddress getRevealedLocalAddress(InetSocketAddress addr) { + SecurityManager sm = System.getSecurityManager(); + if (addr == null || sm == null) + return addr; + + if (!getRevealLocalAddress()) { + // Return loopback address only if security check fails + try{ + sm.checkConnect(addr.getAddress().getHostAddress(), -1); + //Security check passed + } catch (SecurityException e) { + //Return loopback address + addr = getLoopbackAddress(addr.getPort()); + } + } + return addr; + } + + static String getRevealedLocalAddressAsString(InetSocketAddress addr) { + if (!getRevealLocalAddress() && System.getSecurityManager() != null) + addr = getLoopbackAddress(addr.getPort()); + return addr.toString(); + } + + private static boolean getRevealLocalAddress() { + if (!propRevealLocalAddress) { + try { + revealLocalAddress = Boolean.parseBoolean( + AccessController.doPrivileged( + new PrivilegedExceptionAction<String>() { + public String run() { + return System.getProperty( + "jdk.net.revealLocalAddress"); + } + })); + + } catch (Exception e) { + // revealLocalAddress is false + } + propRevealLocalAddress = true; + } + return revealLocalAddress; + } + + private static InetSocketAddress getLoopbackAddress(int port) { + return new InetSocketAddress(InetAddress.getLoopbackAddress(), + port); + } + + /** * Returns any IPv4 address of the given network interface, or * null if the interface does not have any IPv4 addresses. */ @@ -308,6 +402,12 @@ class Net { // package-private private static native boolean isIPv6Available0(); + /* + * Returns 1 for Windows versions that support exclusive binding by default, 0 + * for those that do not, and -1 for Solaris/Linux/Mac OS + */ + private static native int isExclusiveBindAvailable(); + private static native boolean canIPv6SocketJoinIPv4Group0(); private static native boolean canJoin6WithIPv4Group0(); @@ -341,11 +441,12 @@ class Net { // package-private { boolean preferIPv6 = isIPv6Available() && (family != StandardProtocolFamily.INET); - bind0(preferIPv6, fd, addr, port); + bind0(fd, preferIPv6, exclusiveBind, addr, port); } - private static native void bind0(boolean preferIPv6, FileDescriptor fd, - InetAddress addr, int port) + private static native void bind0(FileDescriptor fd, boolean preferIPv6, + boolean useExclBind, InetAddress addr, + int port) throws IOException; static native void listen(FileDescriptor fd, int backlog) throws IOException; diff --git a/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java b/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java index e7b7e1405a..3c569b1e37 100644 --- a/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java +++ b/external/ikvm/openjdk/sun/nio/fs/NetFileSystemProvider.java @@ -338,7 +338,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider } } - return FileChannelImpl.open(open(npath.path, mode, rights, share, options), read, write, append, null); + return FileChannelImpl.open(open(npath.path, mode, rights, share, options), npath.path, read, write, append, null); } private static FileDescriptor open(String path, int mode, int rights, int share, int options) throws IOException diff --git a/external/ikvm/openjdk/sun/reflect/CallerSensitive.java b/external/ikvm/openjdk/sun/reflect/CallerSensitive.java new file mode 100644 index 0000000000..b238baafb3 --- /dev/null +++ b/external/ikvm/openjdk/sun/reflect/CallerSensitive.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.reflect; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +/** + * A method annotated @CallerSensitive is sensitive to its calling class, + * via {@link sun.reflect.Reflection#getCallerClass Reflection.getCallerClass}, + * or via some equivalent. + * + * @author John R. Rose + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({METHOD}) +public @interface CallerSensitive { +} diff --git a/external/ikvm/openjdk/sun/reflect/Reflection.java b/external/ikvm/openjdk/sun/reflect/Reflection.java index 5d237a6356..6cff5746d4 100644 --- a/external/ikvm/openjdk/sun/reflect/Reflection.java +++ b/external/ikvm/openjdk/sun/reflect/Reflection.java @@ -63,6 +63,14 @@ public class Reflection { methodFilterMap.put(sun.misc.Unsafe.class, new String[] {"getUnsafe"}); } + /** Returns the class of the caller of the method calling this method, + ignoring frames associated with java.lang.reflect.Method.invoke() + and its implementation. */ + @CallerSensitive + public static Class getCallerClass() { + return getCallerClass(2); + } + /** Returns the class of the method <code>realFramesToSkip</code> frames up the stack (zero-based), ignoring frames associated with java.lang.reflect.Method.invoke() and its implementation. @@ -72,6 +80,7 @@ public class Reflection { java.lang.reflect.Method.invoke() and its implementation are completely ignored and do not count toward the number of "real" frames skipped. */ + @CallerSensitive public static native Class getCallerClass(int realFramesToSkip); /** Retrieves the access flags written to the class file. For diff --git a/external/ikvm/openjdk/sun/reflect/misc/ReflectUtil.java b/external/ikvm/openjdk/sun/reflect/misc/ReflectUtil.java new file mode 100644 index 0000000000..81468c2013 --- /dev/null +++ b/external/ikvm/openjdk/sun/reflect/misc/ReflectUtil.java @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package sun.reflect.misc; + +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; +import sun.reflect.Reflection; + +public final class ReflectUtil { + + private ReflectUtil() { + } + + public static Class forName(String name) + throws ClassNotFoundException { + checkPackageAccess(name); + return Class.forName(name); + } + + public static Object newInstance(Class cls) + throws InstantiationException, IllegalAccessException { + checkPackageAccess(cls); + return cls.newInstance(); + } + + /* + * Reflection.ensureMemberAccess is overly-restrictive + * due to a bug. We awkwardly work around it for now. + */ + public static void ensureMemberAccess(Class currentClass, + Class memberClass, + Object target, + int modifiers) + throws IllegalAccessException + { + if (target == null && Modifier.isProtected(modifiers)) { + int mods = modifiers; + mods = mods & (~Modifier.PROTECTED); + mods = mods | Modifier.PUBLIC; + + /* + * See if we fail because of class modifiers + */ + Reflection.ensureMemberAccess(currentClass, + memberClass, + target, + mods); + try { + /* + * We're still here so class access was ok. + * Now try with default field access. + */ + mods = mods & (~Modifier.PUBLIC); + Reflection.ensureMemberAccess(currentClass, + memberClass, + target, + mods); + /* + * We're still here so access is ok without + * checking for protected. + */ + return; + } catch (IllegalAccessException e) { + /* + * Access failed but we're 'protected' so + * if the test below succeeds then we're ok. + */ + if (isSubclassOf(currentClass, memberClass)) { + return; + } else { + throw e; + } + } + } else { + Reflection.ensureMemberAccess(currentClass, + memberClass, + target, + modifiers); + } + } + + private static boolean isSubclassOf(Class queryClass, + Class ofClass) + { + while (queryClass != null) { + if (queryClass == ofClass) { + return true; + } + queryClass = queryClass.getSuperclass(); + } + return false; + } + + + /** + * Checks package access on the given class. + * + * If it is a {@link Proxy#isProxyClass(java.lang.Class)} that implements + * a non-public interface (i.e. may be in a non-restricted package), + * also check the package access on the proxy interfaces. + */ + public static void checkPackageAccess(Class<?> clazz) { + checkPackageAccess(clazz.getName()); + if (isNonPublicProxyClass(clazz)) { + checkProxyPackageAccess(clazz); + } + } + + /** + * Checks package access on the given classname. + * This method is typically called when the Class instance is not + * available and the caller attempts to load a class on behalf + * the true caller (application). + */ + public static void checkPackageAccess(String name) { + SecurityManager s = System.getSecurityManager(); + if (s != null) { + String cname = name.replace('/', '.'); + if (cname.startsWith("[")) { + int b = cname.lastIndexOf('[') + 2; + if (b > 1 && b < cname.length()) { + cname = cname.substring(b); + } + } + int i = cname.lastIndexOf('.'); + if (i != -1) { + s.checkPackageAccess(cname.substring(0, i)); + } + } + } + + public static boolean isPackageAccessible(Class clazz) { + try { + checkPackageAccess(clazz); + } catch (SecurityException e) { + return false; + } + return true; + } + + // Returns true if p is an ancestor of cl i.e. class loader 'p' can + // be found in the cl's delegation chain + private static boolean isAncestor(ClassLoader p, ClassLoader cl) { + ClassLoader acl = cl; + do { + acl = acl.getParent(); + if (p == acl) { + return true; + } + } while (acl != null); + return false; + } + + /** + * Returns true if package access check is needed for reflective + * access from a class loader 'from' to classes or members in + * a class defined by class loader 'to'. This method returns true + * if 'from' is not the same as or an ancestor of 'to'. All code + * in a system domain are granted with all permission and so this + * method returns false if 'from' class loader is a class loader + * loading system classes. On the other hand, if a class loader + * attempts to access system domain classes, it requires package + * access check and this method will return true. + */ + public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) { + if (from == null || from == to) + return false; + + if (to == null) + return true; + + return !isAncestor(from, to); + } + + /** + * Check package access on the proxy interfaces that the given proxy class + * implements. + * + * @param clazz Proxy class object + */ + public static void checkProxyPackageAccess(Class<?> clazz) { + SecurityManager s = System.getSecurityManager(); + if (s != null) { + // check proxy interfaces if the given class is a proxy class + if (Proxy.isProxyClass(clazz)) { + for (Class<?> intf : clazz.getInterfaces()) { + checkPackageAccess(intf); + } + } + } + } + + /** + * Access check on the interfaces that a proxy class implements and throw + * {@code SecurityException} if it accesses a restricted package from + * the caller's class loader. + * + * @param ccl the caller's class loader + * @param interfaces the list of interfaces that a proxy class implements + */ + public static void checkProxyPackageAccess(ClassLoader ccl, + Class<?>... interfaces) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + for (Class<?> intf : interfaces) { + ClassLoader cl = intf.getClassLoader(); + if (needsPackageAccessCheck(ccl, cl)) { + checkPackageAccess(intf); + } + } + } + } + + public static final String PROXY_PACKAGE = "com.sun.proxy"; + + /** + * Test if the given class is a proxy class that implements + * non-public interface. Such proxy class may be in a non-restricted + * package that bypasses checkPackageAccess. + */ + public static boolean isNonPublicProxyClass(Class<?> cls) { + String name = cls.getName(); + int i = name.lastIndexOf('.'); + String pkg = (i != -1) ? name.substring(0, i) : ""; + return Proxy.isProxyClass(cls) && !pkg.equals(PROXY_PACKAGE); + } +} |