summaryrefslogtreecommitdiff
path: root/libjava/classpath/java
diff options
context:
space:
mode:
authordoko <doko@138bc75d-0d04-0410-961f-82ee72b054a4>2008-10-21 17:55:01 +0000
committerdoko <doko@138bc75d-0d04-0410-961f-82ee72b054a4>2008-10-21 17:55:01 +0000
commit2bc043354c4edb1f5aad751285060fb722a63ea1 (patch)
tree6de8da5758622565799768e49cd0de6698ca3cb8 /libjava/classpath/java
parentbe9f921eb27de7f5f22e4755df15340ab8042a09 (diff)
downloadgcc-2bc043354c4edb1f5aad751285060fb722a63ea1.tar.gz
libjava/ChangeLog:
2008-10-21 Andrew John Hughes <gnu_andrew@member.fsf.org> * sources.am, Makfile.in: Regenerate. 2008-10-17 Matthias Klose <doko@ubuntu.com> * configure.ac: Fix bashisms. * configure: Regenerate. 2008-10-15 Matthias Klose <doko@ubuntu.com> * configure.ac: Disable build of gjdoc, if configured without --with-antlr-jar or if no antlr.jar found. * configure: Regenerate. 2008-10-09 Andrew John Hughes <gnu_andrew@member.fsf.org> * classpath/configure.ac, * classpath/m4/ac_prog_antlr.m4, * classpath/m4/ac_prog_java.m4, * classpath/tools/Makefile.am: Ported --regen-gjdoc-parser patch and cantlr support from GNU Classpath. 2008-10-06 Andrew Haley <aph@redhat.com> * java/lang/Thread.java (Thread): Always create the ThreadLocalMap when creating a thread. (getThreadLocals) Don't lazily create the ThreadLocalMap. 2008-09-28 Andrew John Hughes <gnu_andrew@member.fsf.org> * classpath/java/lang/ThreadLocalMap.java, * java/lang/ThreadLocalMap$Entry.h, * java/lang/ThreadLocalMap.h, * lib/java/lang/ThreadLocalMap.class, * lib/java/lang/ThreadLocalMap$Entry.class: Add the new files for the ThreadLocal patch. 2008-09-28 Andrew John Hughes <gnu_andrew@member.fsf.org> * classpath/ChangeLog, * classpath/java/lang/InheritableThreadLocal.java, * classpath/java/lang/Thread.java, * classpath/java/lang/ThreadLocal.java: Merge Daniel Frampton's ThreadLocal patch. * gcj/javaprims.h: Updated. * java/lang/Thread.h: Regenerated. * java/lang/Thread.java: Replace WeakIdentityHashMap with ThreadLocalMap. (getThreadLocals()): Likewise. * java/lang/ThreadLocal.h: Regenerated. * java/lang/ThreadLocal.java: (computeNextHash()): New method. (ThreadLocal()): Initialise fastHash. (internalGet()): Updated to match Classpath's get(). (internalSet(Object)): Likewise for set(Object). (internalRemove()): Likewise for remove(). 2008-09-25 Andrew John Hughes <gnu_andrew@member.fsf.org> * classpath/configure, * classpath/configure.ac: Resynchronise with Classpath's configure. * classpath/examples/Makefile.in: Add equivalent support for building as in tools/Makefile.in. * classpath/java/nio/Buffer.java, * classpath/java/nio/ByteBuffer.java, * classpath/java/nio/ByteBufferImpl.java, * classpath/java/nio/CharBuffer.java, * classpath/java/nio/CharBufferImpl.java, * classpath/java/nio/CharSequenceBuffer.java, * classpath/java/nio/CharViewBufferImpl.java, * classpath/java/nio/DirectByteBufferImpl.java, * classpath/java/nio/DoubleBuffer.java, * classpath/java/nio/DoubleBufferImpl.java, * classpath/java/nio/DoubleViewBufferImpl.java, * classpath/java/nio/FloatBuffer.java, * classpath/java/nio/FloatBufferImpl.java, * classpath/java/nio/FloatViewBufferImpl.java, * classpath/java/nio/IntBuffer.java, * classpath/java/nio/IntBufferImpl.java, * classpath/java/nio/IntViewBufferImpl.java, * classpath/java/nio/LongBuffer.java, * classpath/java/nio/LongBufferImpl.java, * classpath/java/nio/LongViewBufferImpl.java, * classpath/java/nio/MappedByteBuffer.java, * classpath/java/nio/MappedByteBufferImpl.java, * classpath/java/nio/ShortBuffer.java, * classpath/java/nio/ShortBufferImpl.java, * classpath/java/nio/ShortViewBufferImpl.java: Replace use of gnu.classpath.Pointer with gnu.gcj.RawData, and fix some formatting issues. * classpath/tools/gnu/classpath/tools/gjdoc/expr/JavaLexer.java, * classpath/tools/gnu/classpath/tools/gjdoc/expr/JavaLexer.smap, * classpath/tools/gnu/classpath/tools/gjdoc/expr/JavaRecognizer.java, * classpath/tools/gnu/classpath/tools/gjdoc/expr/JavaRecognizer.smap, * classpath/tools/gnu/classpath/tools/gjdoc/expr/JavaTokenTypes.java, * classpath/tools/gnu/classpath/tools/gjdoc/expr/JavaTokenTypes.txt: Regenerated (later version of antlr). * java/nio/Buffer.h: Regenerated. * java/nio/Buffer.java: Ported changes from Classpath. * java/nio/ByteBuffer.h, * java/nio/CharBuffer.h: Regenerated. * java/nio/DirectByteBufferImpl.java: Ported changes from Classpath. * java/nio/DoubleBuffer.h, * java/nio/FloatBuffer.h, * java/nio/IntBuffer.h, * java/nio/LongBuffer.h, * java/nio/MappedByteBuffer.h, * java/nio/MappedByteBufferImpl.h: Regenerated. * java/nio/MappedByteBufferImpl.java: Ported changes from Classpath. * java/nio/ShortBuffer.h: Regenerated. 2008-09-24 Matthias Klose <doko@ubuntu.com> * configure.ac: Search for antlr.jar, if not configured. * configure: Regenerate. 2008-09-24 Matthias Klose <doko@ubuntu.com> * Makefile.am: Build a gjdoc binary, if enabled. * configure.ac: Add options --disable-gjdoc, --with-antlr-jar=file. * Makefile.in, */Makefile.in, configure: Regenerate. 2008-09-22 Andrew Haley <aph@redhat.com> * java/lang/String.java (toString(char[], int, int)): New method. 2008-09-14 Matthias Klose <doko@ubuntu.com> Import GNU Classpath (libgcj-import-20080914). * Regenerate class and header files. * Regenerate auto* files. * configure.ac: Don't pass --disable-gjdoc to classpath. * sources.am: Regenerated. * HACKING: Mention to build gjdoc in maintainer builds. * gnu/classpath/Configuration.java: Update classpath version. * gcj/javaprims.h: Update. 2008-09-08 Andrew John Hughes <gnu_andrew@member.fsf.org> * Makefile.am: Replace natStringBuffer.cc and natStringBuilder.cc with natAbstractStringBuffer.cc. * Makefile.in: Regenerated. * java/lang/AbstractStringBuffer.java: (append(int)): Made native. (regionMatches(int,String)): Likewise. * java/lang/StringBuffer.h: Regenerated. * java/lang/StringBuffer.java: Remerged with GNU Classpath. * java/lang/StringBuilder.h: Regenerated. * java/lang/StringBuilder.java: Remerged with GNU Classpath. * java/lang/natAbstractStringBuffer.cc: Provide common native methods for StringBuffer and StringBuilder. * java/lang/natStringBuffer.cc, * java/lang/natStringBuilder.cc: Removed. 2008-09-04 Andrew John Hughes <gnu_andrew@member.fsf.org> * Makefile.in, * classpath/configure: Regenerated. * gnu/gcj/util/natDebug.cc, * gnu/gcj/xlib/natColormap.cc, * gnu/gcj/xlib/natDisplay.cc, * gnu/gcj/xlib/natDrawable.cc, * gnu/gcj/xlib/natFont.cc, * gnu/gcj/xlib/natWMSizeHints.cc, * gnu/gcj/xlib/natWindow.cc, * gnu/gcj/xlib/natXImage.cc: Add :: prefix to namespaces. * java/io/CharArrayWriter.h, * java/lang/StringBuffer.h: Regenerated using patched gjavah. * java/lang/natStringBuffer.cc: Fix naming of append(jint). * java/sql/Timestamp.h: Regenerated using patched gjavah. * jni.cc: Rename p to functions to match change in GNU Classpath. * scripts/makemake.tcl: Switch gnu.java.math to BC compilation. * sources.am: Regenerated. 2008-08-21 Andrew John Hughes <gnu_andrew@member.fsf.org> * Makefile.in: Updated location of Configuration.java. * classpath/lib/gnu/java/locale/LocaleData.class: Regenerated. 2008-08-18 Andrew John Hughes <gnu_andrew@member.fsf.org> * Makefile.in: Updated with new Java files. * classpath/configure: Regenerated. * classpath/tools/Makefile.am: Add missing use of GJDOC_EX so --disable-gjdoc works. * classpath/tools/Makefile.in: Regenerated. 2008-08-15 Matthias Klose <doko@ubuntu.com> Import GNU Classpath (libgcj-import-20080811). * Regenerate class and header files. * Regenerate auto* files. * configure.ac: Don't pass --with-fastjar to classpath, substitute new dummy value in classpath/gnu/classpath/Configuration.java.in, pass --disable-gjdoc to classpath. * scripts/makemake.tcl: * sources.am: Regenerated. * java/lang/AbstractStringBuffer.java, gnu/java/lang/VMCPStringBuilder.java: New, copied from classpath, use System instead of VMSystem. * java/lang/StringBuffer.java: Merge from classpath. * java/lang/ClassLoader.java: Merge from classpath. * gcj/javaprims.h: Update class definitions, remove _Jv_jobjectRefType, jobjectRefType definitions. libjava/classpath/ChangeLog.gcj: 2008-10-21 Matthias Klose <doko@ubuntu.com> * classpath/tools/gnu/classpath/tools/gjdoc/expr/Java*: Move from ... * classpath/tools/generated/gnu/classpath/tools/gjdoc/expr/ ... here. * Update .class files. 2008-10-21 Andrew John Hughes <gnu_andrew@member.fsf.org> * tools/Makefile.am: Always generate parser in the srcdir. 2008-10-21 Matthias Klose <doko@ubuntu.com> * doc/Makefile.am (MAINTAINERCLEANFILES): Add gjdoc.1. * doc/Makefile.in: Regenerate. 2008-10-20 Matthias Klose <doko@ubuntu.com> * configure.ac: Don't check for working java, if not configured with --enable-java-maintainer-mode. * configure: Regenerate. 2008-10-19 Matthias Klose <doko@ubuntu.com> * m4/ac_prog_java.m4: Revert previous change. * m4/ac_prog_javac.m4: Apply it here. * configure: Regenerate. 2008-10-19 Matthias Klose <doko@ubuntu.com> * m4/ac_prog_javac.m4: Don't check for working javac, if not configured with --enable-java-maintainer-mode. * configure: Regenerate. * Makefile.in, */Makefile.in: Regenerate. 2008-09-30 Matthias Klose <doko@ubuntu.com> * m4/ac_prog_antlr.m4: Check for cantlr binary as well. 2008-09-29 Matthias Klose <doko@ubuntu.com> * m4/ac_prog_antlr.m4: Check for antlr binary as well. 2008-09-28 Matthias Klose <doko@ubuntu.com> * PR libgcj/37636. Revert: 2008-02-20 Matthias Klose <doko@ubuntu.com> * tools/Makefile.am ($(TOOLS_ZIP)): Revert part of previous change, Do copy resource files in JAVA_MAINTAINER_MODE only. * tools/Makefile.in: Regenerate. 2008-09-14 Matthias Klose <doko@ubuntu.com> * m4/ac_prog_javac_works.m4, m4/ac_prog_javac.m4, m4/acinclude.m4: Revert local changes. * m4/ac_prog_antlr.m4: Check for an runantlr binary. * tools/Makefile.am, lib/Makefile.am: Revert local changes (JCOMPILER). * tools/Makefile.am: Remove USE_JAVAC_FLAGS, pass ANTLR_JAR in GLIBJ_CLASSPATH. 2008-09-14 Matthias Klose <doko@ubuntu.com> Revert: Daniel Frampton <zyridium at zyridium.net> * AUTHORS: Added. * java/lang/InheritableThreadLocal.java, * java/lang/Thread.java, * java/lang/ThreadLocal.java: Modified to use java.lang.ThreadLocalMap. * java/lang/ThreadLocalMap.java: New cheaper ThreadLocal-specific WeakHashMap. 2008-08-15 Matthias Klose <doko@ubuntu.com> * m4/acinclude.m4 (CLASSPATH_JAVAC_MEM_CHECK): Remove unknown args for javac. libjava/classpath/ChangeLog: 2008-10-20 Andrew John Hughes <gnu_andrew@member.fsf.org> * m4/ac_prog_antlr.m4: Remove redundant checks. * tools/Makefile.am: Use gjdoc_gendir when calling antlr. 2008-10-15 Andrew John Hughes <gnu_andrew@member.fsf.org> * configure.ac: Remove superfluous AC_PROG_JAVA call. 2008-10-06 Andrew John Hughes <gnu_andrew@member.fsf.org> * m4/ac_prog_antlr: Check for cantlr as well. * tools/Makefile.am: Only build GJDoc parser when both CREATE_GJDOC and CREATE_GJDOC_PARSER are on. 2008-10-02 Andrew John Hughes <gnu_andrew@member.fsf.org> * configure.ac: Add regen-gjdoc-parser option, and separate antlr tests. * m4/ac_prog_antlr.m4: Turn single test into AC_LIB_ANTLR and AC_PROG_ANTLR. * m4/ac_prog_java.m4: Quote tests. * tools/Makefile.am: Support CREATE_GJDOC_PARSER option. 2008-09-14 Andrew John Hughes <gnu_andrew@member.fsf.org> * examples/Makefile.am: Check lib directly as well as glibj.zip for boot classes. * m4/acinclude.m4: Only require the class files to be built to allow the tools and examples to be built, not the installation of glibj.zip. * tools/Makefile.am: Check lib directly as well as glibj.zip for boot classes. 2008-09-13 Andrew John Hughes <gnu_andrew@member.fsf.org> * examples/Makefile.am, * lib/Makefile.am: Add GCJ rules. * m4/ac_prog_javac.m4: Check whether JAVAC is gcj. * m4/ac_prog_javac_works.m4: Add GCJ rules. * m4/acinclude.m4: Don't bother checking for -J if using GCJ. * tools/Makefile.am: Add GCJ rules. 2007-08-23 Daniel Frampton <zyridium@zyridium.net> * AUTHORS: Added. * java/lang/InheritableThreadLocal.java, * java/lang/Thread.java, * java/lang/ThreadLocal.java: Modified to use java.lang.ThreadLocalMap. * java/lang/ThreadLocalMap.java: New cheaper ThreadLocal-specific WeakHashMap. 2008-02-07 Ian Rogers <ian.rogers@manchester.ac.uk> * java/util/zip/ZipEntry.java: Use byte fields instead of integer fields, store the time as well as the DOS time and don't retain a global Calendar instance. (setDOSTime(int)): Set KNOWN_DOSTIME instead of KNOWN_TIME, and unset KNOWN_TIME. (getDOSTime()): Compute DOS time from UNIX time only when needed. (clone()): Provide cloning via the ZipEntry constructor where possible. (setTime(long)): Don't compute DOS time at this point. (getCalendar()): Removed. 2008-09-09 Andrew John Hughes <gnu_andrew@member.fsf.org> * tools/gnu/classpath/tools/getopt/Parser.java: (setHeader(String)): Make synchronized. (setFooter(String)): Likewise. * tools/gnu/classpath/tools/rmic/SourceGiopRmicCompiler.java, (reset()): Make synchronized. (name(Class)): Likewise. 2008-09-04 Robert Schuster <robertschuster@fsfe.org> * gnu/java/nio/charset/ByteDecodeLoopHelper: (arrayDecodeLoop): Added new break label, escape to that label. * gnu/java/nio/charset/ByteEncodeLoopHelper: (arrayDecodeLoop): Added new break label, escape to that label. 2008-09-04 Robert Schuster <robertschuster@fsfe.org> * java/text/DecimalFormat.java: (scanFix): Use 'i + 1' when looking at following character. (scanNegativePattern): Dito. 2008-09-02 Andrew John Hughes <gnu_andrew@member.fsf.org> * tools/gnu/classpath/tools/javah/ClassWrapper.java: (makeVtable()): Populate methodNameMap. (printMethods(CniPrintStream)): Always use pre-populated methodNameMap for bridge targets. 2008-09-01 Mario Torre <neugens@aicas.com> * gnu/java/awt/peer/x/XImage.java (XImageProducer): remove @Override annotation to allow compilation on javac < 1.6 and ecj < 3.4. 2008-09-01 Mario Torre <neugens@aicas.com> * gnu/java/awt/peer/x/XGraphicsDevice.java (getDisplay): fix to support new Escher API. * gnu/java/awt/peer/x/XImage.java (getSource): method implemented. * gnu/java/awt/peer/x/XImage.java (XImageProducer): implement ImageProducer for getSource. 2008-09-01 Andrew John Hughes <gnu_andrew@member.fsf.org> * gnu/java/util/regex/BacktrackStack.java, * gnu/java/util/regex/CharIndexed.java, * gnu/java/util/regex/CharIndexedCharArray.java, * gnu/java/util/regex/CharIndexedCharSequence.java, * gnu/java/util/regex/CharIndexedInputStream.java, * gnu/java/util/regex/CharIndexedString.java, * gnu/java/util/regex/CharIndexedStringBuffer.java, * gnu/java/util/regex/RE.java, * gnu/java/util/regex/REException.java, * gnu/java/util/regex/REFilterInputStream.java, * gnu/java/util/regex/REMatch.java, * gnu/java/util/regex/REMatchEnumeration.java, * gnu/java/util/regex/RESyntax.java, * gnu/java/util/regex/REToken.java, * gnu/java/util/regex/RETokenAny.java, * gnu/java/util/regex/RETokenBackRef.java, * gnu/java/util/regex/RETokenChar.java, * gnu/java/util/regex/RETokenEnd.java, * gnu/java/util/regex/RETokenEndOfPreviousMatch.java, * gnu/java/util/regex/RETokenEndSub.java, * gnu/java/util/regex/RETokenIndependent.java, * gnu/java/util/regex/RETokenLookAhead.java, * gnu/java/util/regex/RETokenLookBehind.java, * gnu/java/util/regex/RETokenNamedProperty.java, * gnu/java/util/regex/RETokenOneOf.java, * gnu/java/util/regex/RETokenPOSIX.java, * gnu/java/util/regex/RETokenRange.java, * gnu/java/util/regex/RETokenRepeated.java, * gnu/java/util/regex/RETokenStart.java, * gnu/java/util/regex/RETokenWordBoundary.java, * gnu/java/util/regex/UncheckedRE.java: Fix indentation. 2008-09-01 Andrew John Hughes <gnu_andrew@member.fsf.org> * gnu/java/util/regex/RETokenStart.java: (getMaximumLength()): Add Override annotation. (matchThis(CharIndexed, REMatch)): Likewise. (returnsFixedLengthMatches()): Renamed from returnsFixedLengthmatches and added Override annotation. (findFixedLengthMatches(CharIndexed,REMatch,int)): Add Override annotation. (dump(CPStringBuilder)): Likewise. * gnu/javax/print/ipp/IppRequest.java: (RequestWriter.writeOperationAttributes(AttributeSet)): Throw exception, don't just create and drop it. * javax/management/MBeanServerPermission.java: (MBeanServerPermissionCollection.add(Permission)): Compare against individual Strings not the entire array, and store the result of replace. * javax/swing/text/html/StyleSheet.java: (setBaseFontSize(size)): Store result of trim(). 2008-09-01 Andrew John Hughes <gnu_andrew@member.fsf.org> * javax/tools/FileObject.java: (openReader(boolean)): Document new parameter. 2008-03-27 Michael Franz <mvfranz@gmail.com> PR classpath/35690: * javax/tools/FileObject.java: (toUri()): Fix case from toURI. (openReader(boolean)): Add missing boolean argument. 2008-08-26 Andrew John Hughes <gnu_andrew@member.fsf.org> PR classpath/35487: * gnu/javax/management/Server.java: (beans): Change to ConcurrentHashMap. (defaultDomain): Make final. (outer): Likewise. (LazyListenersHolder): Added to wrap listeners, also now a ConcurrentHashMap, providing lazy initialisation safely. (sequenceNumber): Documented. (getBean(ObjectName)): Remove redundant cast. (addNotificationListener(ObjectName,NotificationListener, NotificationFilter,Object)): Remove map initialisation and use holder. (getObjectInstance(ObjectName)): Remove redundant cast. (registerMBean(Object,ObjectName)): Add bean atomically. (removeNotificationListener(ObjectName,NotificationListener)): Simplified. (removeNotificationListener(ObjectName,NotificationListener, NotificationFilter,Object)): Likewise. (notify(ObjectName,String)): Documented. 2008-08-26 Andrew John Hughes <gnu_andrew@member.fsf.org> * gnu/javax/management/Server.java: Genericised. 2008-08-26 Andrew John Hughes <gnu_andrew@member.fsf.org> * gnu/javax/management/Translator.java: Genericised. 2008-08-26 Andrew John Hughes <gnu_andrew@member.fsf.org> * javax/management/DefaultLoaderRepository.java, * javax/management/JMX.java, * javax/management/MBeanAttributeInfo.java, * javax/management/MBeanConstructorInfo.java, * javax/management/MBeanOperationInfo.java, * javax/management/MBeanServerDelegate.java: Fix warnings due to generics. 2008-08-25 Andrew John Hughes <gnu_andrew@member.fsf.org> * javax/management/MBeanPermission.java, * javax/management/MBeanServerDelegate.java, * javax/management/MBeanServerFactory.java, * javax/management/MBeanServerInvocationHandler.java, * javax/management/MBeanServerPermission.java: Fix warnings due to use of non-generic collections. 2008-08-25 Mario Torre <neugens@aicas.com> * gnu/javax/rmi/CORBA/RmiUtilities.java (readValue): check if sender is null to avoid NPE. 2008-08-22 Mario Torre <neugens@aicas.com> * gnu/CORBA/OrbFunctional.java (set_parameters): Fix NullPointerException checking when param is null. 2008-08-23 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/util/regex/Matcher.java: (reset()): Reset append position so we don't try and append to the end of the old input. 2008-08-22 Andrew John Hughes <gnu_andrew@member.fsf.org> PR classpath/32028: * m4/acinclude.m4: Also allow versions of GJDoc from 0.8* on, as CVS is 0.8.0-pre. 2008-08-21 Andrew John Hughes <gnu_andrew@member.fsf.org> PR classpath/32028: * m4/acinclude.m4: (CLASSPATH_WITH_GJDOC): Ensure version 0.7.9 is being used. 2008-08-20 Andrew John Hughes <gnu_andrew@member.fsf.org> * tools/Makefile.am: Add taglets subdirectory to list of excluded paths when GJDoc is not compiled. 2008-08-19 David P Grove <groved@us.ibm.com> * scripts/check_jni_methods.sh.in: Fix build issue on AIX by splitting generation of method list. 2008-08-18 Andrew John Hughes <gnu_andrew@member.fsf.org> * native/jni/gstreamer-peer/gst_native_pipeline.c: (get_free_space(int)): Use #else not #elif when there is no condition. 2008-08-17 Andrew John Hughes <gnu_andrew@member.fsf.org> PR classpath/31895: * java/text/DecimalFormat.java: (setCurrency(Currency)): Update prefixes and suffixes when currency changes. * java/text/DecimalFormatSymbols.java: (DecimalFormatSymbols(Locale)): Set locale earlier so it can be used by setCurrency(Currency). (setCurrency(Currency)): Set the symbol correctly using the locale of the instance. * java/util/Currency.java: Throw error instead of just printing a message. 2008-08-17 Andrew John Hughes <gnu_andrew@member.fsf.org> * javax/activation/ActivationDataFlavor.java: Suppress warnings from public API. (mimeType): Made final. (representationClass): Added generic type and made final. (normalizeMimeTypeParameter(String,String)): Use CPStringBuilder. * javax/activation/CommandInfo.java: (verb): Made final. (className): Made final. * javax/activation/DataHandler.java: (dataSource): Made final. * javax/activation/FileDataSource.java: (file): Made final. * javax/activation/MailcapCommandMap.java: Use generics on collections and CPStringBuilder instead of StringBuffer. * javax/activation/MimeType.java: (toString()): Use CPStringBuilder. (getBaseType()): Likewise. * javax/activation/MimeTypeParameterList.java: Use generics on collections and CPStringBuilder instead of StringBuffer. * javax/activation/MimeTypeParseException.java: (MimeTypeParseException(String,String)): Use CPStringBuilder. * javax/activation/MimetypesFileTypeMap.java: Use generics on collections and CPStringBuilder instead of StringBuffer. * javax/activation/URLDataSource.java: (url): Made final. 2008-08-17 Andrew John Hughes <gnu_andrew@member.fsf.org> * gnu/javax/activation/viewers/ImageViewer.java, * gnu/javax/activation/viewers/TextEditor.java, * gnu/javax/activation/viewers/TextViewer.java, * javax/activation/ActivationDataFlavor.java, * javax/activation/CommandInfo.java, * javax/activation/CommandMap.java, * javax/activation/CommandObject.java, * javax/activation/DataContentHandler.java, * javax/activation/DataContentHandlerFactory.java, * javax/activation/DataHandler.java, * javax/activation/DataHandlerDataSource.java, * javax/activation/DataSource.java, * javax/activation/DataSourceDataContentHandler.java, * javax/activation/FileDataSource.java, * javax/activation/FileTypeMap.java, * javax/activation/MailcapCommandMap.java, * javax/activation/MimeType.java, * javax/activation/MimeTypeParameterList.java, * javax/activation/MimeTypeParseException.java, * javax/activation/MimetypesFileTypeMap.java, * javax/activation/ObjectDataContentHandler.java, * javax/activation/URLDataSource.java, * javax/activation/UnsupportedDataTypeException.java, * javax/activation/package.html, * resource/META-INF/mailcap.default, * resource/META-INF/mimetypes.default: Import GNU JAF CVS as of 17/08/2008. 2006-04-25 Archit Shah <ashah@redhat.com> * javax/activation/MimeTypeParameterList.java: Insert ';' separator before parameter list. 2005-06-29 Xavier Poinsard <xpoinsard@openpricer.com> * javax/activation/ObjectDataContentHandler.java: Fixed typo. 2005-05-28 Chris Burdess <dog@bluezoo.org> * javax/activation/CommandMap.java, * javax/activation/MailcapCommandMap.java: Updated to JAF 1.1. 2004-06-09 Chris Burdess <dog@bluezoo.org> * javax/activation/MailcapCommandMap.java: Fixed bug whereby x-java prefix was not attempted. 2008-08-17 Andrew John Hughes <gnu_andrew@member.fsf.org> * AUTHORS: Added Laszlo. 2008-04-20 Andrew John Hughes <gnu_andrew@member.fsf.org> PR classpath/30436: * java/util/Scanner.java: Fix package to be java.util and correct indentation. 2007-07-25 Laszlo Andras Hernadi <e0327023@student.tuwien.ac.at> PR classpath/30436: * java/util/Scanner.java: Initial implementation. 2008-08-17 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/util/regex/Matcher.java: (toMatchResult()): Implemented. 2008-08-13 Joshua Sumali <jsumali@redhat.com> * doc/Makefile.am (gjdoc.pod): Generate gjdoc pod from cp-tools.texinfo instead of invoke.texi. Remove invoke.texi from EXTRA_DIST. * doc/invoke.texi: Removed and merged into ... * doc/cp-tools.texinfo: Here 2008-08-12 Robert Schuster <robertschuster@fsfe.org> * native/jni/java-net/local.c (local_bind): Removed fprintf call, fixed access outside of array bounds. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141271 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/java')
-rw-r--r--libjava/classpath/java/awt/AlphaComposite.java35
-rw-r--r--libjava/classpath/java/awt/Component.java6
-rw-r--r--libjava/classpath/java/awt/Container.java4
-rw-r--r--libjava/classpath/java/awt/JobAttributes.java4
-rw-r--r--libjava/classpath/java/awt/MouseInfo.java7
-rw-r--r--libjava/classpath/java/awt/datatransfer/MimeType.java4
-rw-r--r--libjava/classpath/java/awt/event/ActionEvent.java8
-rw-r--r--libjava/classpath/java/awt/event/ComponentEvent.java4
-rw-r--r--libjava/classpath/java/awt/event/HierarchyEvent.java4
-rw-r--r--libjava/classpath/java/awt/event/InputEvent.java3
-rw-r--r--libjava/classpath/java/awt/event/InputMethodEvent.java6
-rw-r--r--libjava/classpath/java/awt/event/KeyEvent.java3
-rw-r--r--libjava/classpath/java/awt/event/MouseEvent.java3
-rw-r--r--libjava/classpath/java/awt/event/WindowEvent.java4
-rw-r--r--libjava/classpath/java/awt/font/TextLayout.java4
-rw-r--r--libjava/classpath/java/awt/image/BandedSampleModel.java3
-rw-r--r--libjava/classpath/java/awt/image/BufferedImage.java6
-rw-r--r--libjava/classpath/java/awt/image/ColorModel.java4
-rw-r--r--libjava/classpath/java/awt/image/ComponentColorModel.java2
-rw-r--r--libjava/classpath/java/awt/image/DirectColorModel.java6
-rw-r--r--libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java3
-rw-r--r--libjava/classpath/java/awt/image/Raster.java4
-rw-r--r--libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java3
-rw-r--r--libjava/classpath/java/awt/image/WritableRaster.java23
-rw-r--r--libjava/classpath/java/beans/Statement.java4
-rw-r--r--libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java5
-rw-r--r--libjava/classpath/java/io/BufferedReader.java4
-rw-r--r--libjava/classpath/java/io/DataInputStream.java6
-rw-r--r--libjava/classpath/java/io/File.java6
-rw-r--r--libjava/classpath/java/io/StreamTokenizer.java8
-rw-r--r--libjava/classpath/java/lang/AbstractStringBuffer.java1037
-rw-r--r--libjava/classpath/java/lang/Byte.java18
-rw-r--r--libjava/classpath/java/lang/Character.java13
-rw-r--r--libjava/classpath/java/lang/ClassLoader.java2
-rw-r--r--libjava/classpath/java/lang/Double.java41
-rw-r--r--libjava/classpath/java/lang/Enum.java5
-rw-r--r--libjava/classpath/java/lang/Float.java42
-rw-r--r--libjava/classpath/java/lang/InheritableThreadLocal.java24
-rw-r--r--libjava/classpath/java/lang/Integer.java126
-rw-r--r--libjava/classpath/java/lang/Long.java146
-rw-r--r--libjava/classpath/java/lang/Short.java19
-rw-r--r--libjava/classpath/java/lang/String.java3
-rw-r--r--libjava/classpath/java/lang/StringBuffer.java414
-rw-r--r--libjava/classpath/java/lang/StringBuilder.java505
-rw-r--r--libjava/classpath/java/lang/Thread.java16
-rw-r--r--libjava/classpath/java/lang/ThreadLocal.java39
-rw-r--r--libjava/classpath/java/lang/ThreadLocalMap.java325
-rw-r--r--libjava/classpath/java/lang/Throwable.java6
-rw-r--r--libjava/classpath/java/lang/reflect/AccessibleObject.java51
-rw-r--r--libjava/classpath/java/lang/reflect/Constructor.java453
-rw-r--r--libjava/classpath/java/lang/reflect/Field.java735
-rw-r--r--libjava/classpath/java/lang/reflect/Method.java497
-rw-r--r--libjava/classpath/java/lang/reflect/Modifier.java24
-rw-r--r--libjava/classpath/java/lang/reflect/Proxy.java6
-rw-r--r--libjava/classpath/java/math/BigDecimal.java12
-rw-r--r--libjava/classpath/java/math/BigInteger.java566
-rw-r--r--libjava/classpath/java/net/Inet4Address.java4
-rw-r--r--libjava/classpath/java/net/Inet6Address.java4
-rw-r--r--libjava/classpath/java/net/NetworkInterface.java54
-rw-r--r--libjava/classpath/java/net/SocketPermission.java4
-rw-r--r--libjava/classpath/java/net/URI.java20
-rw-r--r--libjava/classpath/java/net/URLClassLoader.java6
-rw-r--r--libjava/classpath/java/net/URLDecoder.java4
-rw-r--r--libjava/classpath/java/net/URLEncoder.java4
-rw-r--r--libjava/classpath/java/net/URLStreamHandler.java4
-rw-r--r--libjava/classpath/java/nio/Buffer.java18
-rw-r--r--libjava/classpath/java/nio/ByteBuffer.java16
-rw-r--r--libjava/classpath/java/nio/ByteBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/CharBuffer.java18
-rw-r--r--libjava/classpath/java/nio/CharBufferImpl.java12
-rw-r--r--libjava/classpath/java/nio/CharSequenceBuffer.java9
-rw-r--r--libjava/classpath/java/nio/CharViewBufferImpl.java20
-rw-r--r--libjava/classpath/java/nio/DirectByteBufferImpl.java6
-rw-r--r--libjava/classpath/java/nio/DoubleBuffer.java15
-rw-r--r--libjava/classpath/java/nio/DoubleBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/DoubleViewBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/FloatBuffer.java15
-rw-r--r--libjava/classpath/java/nio/FloatBufferImpl.java9
-rw-r--r--libjava/classpath/java/nio/FloatViewBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/IntBuffer.java18
-rw-r--r--libjava/classpath/java/nio/IntBufferImpl.java6
-rw-r--r--libjava/classpath/java/nio/IntViewBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/LongBuffer.java15
-rw-r--r--libjava/classpath/java/nio/LongBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/LongViewBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/MappedByteBuffer.java8
-rw-r--r--libjava/classpath/java/nio/MappedByteBufferImpl.java5
-rw-r--r--libjava/classpath/java/nio/ShortBuffer.java16
-rw-r--r--libjava/classpath/java/nio/ShortBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/ShortViewBufferImpl.java18
-rw-r--r--libjava/classpath/java/nio/channels/FileLock.java5
-rw-r--r--libjava/classpath/java/rmi/activation/Activatable.java6
-rw-r--r--libjava/classpath/java/rmi/dgc/VMID.java4
-rw-r--r--libjava/classpath/java/security/AlgorithmParameterGenerator.java4
-rw-r--r--libjava/classpath/java/security/AlgorithmParameters.java4
-rw-r--r--libjava/classpath/java/security/CodeSource.java4
-rw-r--r--libjava/classpath/java/security/KeyFactory.java4
-rw-r--r--libjava/classpath/java/security/KeyPairGenerator.java4
-rw-r--r--libjava/classpath/java/security/MessageDigest.java8
-rw-r--r--libjava/classpath/java/security/Permission.java4
-rw-r--r--libjava/classpath/java/security/PermissionCollection.java4
-rw-r--r--libjava/classpath/java/security/ProtectionDomain.java4
-rw-r--r--libjava/classpath/java/security/SecureRandom.java3
-rw-r--r--libjava/classpath/java/security/Signature.java4
-rw-r--r--libjava/classpath/java/security/cert/CertPath.java4
-rw-r--r--libjava/classpath/java/security/cert/CertPathBuilder.java4
-rw-r--r--libjava/classpath/java/security/cert/CertPathValidator.java4
-rw-r--r--libjava/classpath/java/security/cert/CertStore.java4
-rw-r--r--libjava/classpath/java/security/cert/PKIXBuilderParameters.java4
-rw-r--r--libjava/classpath/java/security/cert/PKIXCertPathBuilderResult.java4
-rw-r--r--libjava/classpath/java/security/cert/PolicyQualifierInfo.java6
-rw-r--r--libjava/classpath/java/security/cert/X509CRLSelector.java3
-rw-r--r--libjava/classpath/java/security/cert/X509CertSelector.java3
-rw-r--r--libjava/classpath/java/text/AttributedString.java4
-rw-r--r--libjava/classpath/java/text/ChoiceFormat.java10
-rw-r--r--libjava/classpath/java/text/CollationElementIterator.java4
-rw-r--r--libjava/classpath/java/text/Collator.java2
-rw-r--r--libjava/classpath/java/text/DateFormat.java90
-rw-r--r--libjava/classpath/java/text/DateFormatSymbols.java98
-rw-r--r--libjava/classpath/java/text/DecimalFormat.java53
-rw-r--r--libjava/classpath/java/text/DecimalFormatSymbols.java4
-rw-r--r--libjava/classpath/java/text/Format.java2
-rw-r--r--libjava/classpath/java/text/MessageFormat.java8
-rw-r--r--libjava/classpath/java/text/NumberFormat.java2
-rw-r--r--libjava/classpath/java/text/RuleBasedCollator.java2
-rw-r--r--libjava/classpath/java/text/SimpleDateFormat.java30
-rw-r--r--libjava/classpath/java/util/AbstractCollection.java4
-rw-r--r--libjava/classpath/java/util/AbstractMap.java4
-rw-r--r--libjava/classpath/java/util/ArrayList.java21
-rw-r--r--libjava/classpath/java/util/Arrays.java24
-rw-r--r--libjava/classpath/java/util/BitSet.java5
-rw-r--r--libjava/classpath/java/util/Calendar.java36
-rw-r--r--libjava/classpath/java/util/Collections.java4
-rw-r--r--libjava/classpath/java/util/Currency.java2
-rw-r--r--libjava/classpath/java/util/Date.java4
-rw-r--r--libjava/classpath/java/util/Formatter.java28
-rw-r--r--libjava/classpath/java/util/Hashtable.java4
-rw-r--r--libjava/classpath/java/util/Locale.java7
-rw-r--r--libjava/classpath/java/util/Properties.java42
-rw-r--r--libjava/classpath/java/util/PropertyResourceBundle.java19
-rw-r--r--libjava/classpath/java/util/ResourceBundle.java70
-rw-r--r--libjava/classpath/java/util/Scanner.java2223
-rw-r--r--libjava/classpath/java/util/Stack.java6
-rw-r--r--libjava/classpath/java/util/TimeZone.java6
-rw-r--r--libjava/classpath/java/util/TreeMap.java6
-rw-r--r--libjava/classpath/java/util/Vector.java43
-rw-r--r--libjava/classpath/java/util/logging/FileHandler.java4
-rw-r--r--libjava/classpath/java/util/logging/Logger.java4
-rw-r--r--libjava/classpath/java/util/logging/SimpleFormatter.java4
-rw-r--r--libjava/classpath/java/util/logging/XMLFormatter.java20
-rw-r--r--libjava/classpath/java/util/prefs/AbstractPreferences.java55
-rw-r--r--libjava/classpath/java/util/regex/Matcher.java289
-rw-r--r--libjava/classpath/java/util/regex/Pattern.java6
-rw-r--r--libjava/classpath/java/util/regex/PatternSyntaxException.java4
-rw-r--r--libjava/classpath/java/util/zip/Deflater.java2
-rw-r--r--libjava/classpath/java/util/zip/Inflater.java2
-rw-r--r--libjava/classpath/java/util/zip/ZipEntry.java166
-rw-r--r--libjava/classpath/java/util/zip/ZipFile.java2
158 files changed, 7688 insertions, 1618 deletions
diff --git a/libjava/classpath/java/awt/AlphaComposite.java b/libjava/classpath/java/awt/AlphaComposite.java
index addd1e71327..a668fdae696 100644
--- a/libjava/classpath/java/awt/AlphaComposite.java
+++ b/libjava/classpath/java/awt/AlphaComposite.java
@@ -158,18 +158,53 @@ public final class AlphaComposite implements Composite
return new AlphaCompositeContext(this, srcColorModel, dstColorModel);
}
+ /**
+ * Return an <code>AlphaComposite</code> similar to <code>this</code>,
+ * that uses the specified rule. If <code>rule</code> is the same as
+ * <code>this.rule</code>, then <code>this</code> is returned.
+ *
+ * @since 1.6
+ */
+ public AlphaComposite derive(int rule)
+ {
+ if (this.rule == rule)
+ return this;
+ else
+ return AlphaComposite.getInstance(rule, this.getAlpha());
+ }
+
+ /**
+ * Return an <code>AlphaComposite</code> similar to <code>this</code>,
+ * that uses the specified <code>alpha</code>.
+ *
+ * If <code>alph</code> is the same as <code>this.alpha</code>,
+ * then <code>this</code> is returned.
+ *
+ * @since 1.6
+ */
+ public AlphaComposite derive(float alpha)
+ {
+ if (this.getAlpha() == alpha)
+ return this;
+ else
+ return AlphaComposite.getInstance(this.getRule(), alpha);
+ }
+
public float getAlpha()
{
return alpha;
}
+
public int getRule()
{
return rule;
}
+
public int hashCode()
{
return 31 * Float.floatToIntBits(alpha) + rule;
}
+
public boolean equals(Object o)
{
if (! (o instanceof AlphaComposite))
diff --git a/libjava/classpath/java/awt/Component.java b/libjava/classpath/java/awt/Component.java
index fe4fb9b8b0d..44676ba9dd3 100644
--- a/libjava/classpath/java/awt/Component.java
+++ b/libjava/classpath/java/awt/Component.java
@@ -43,6 +43,8 @@ package java.awt;
import gnu.java.awt.ComponentReshapeEvent;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.AdjustmentEvent;
@@ -175,7 +177,7 @@ public abstract class Component
/**
* Constant returned by the <code>getAlignmentY</code> and
* <code>getAlignmentX</code> methods to indicate
- * that the component wishes to be aligned to the center relative to
+ * that the component wishes to be aligned to the centdisper relative to
* other components.
*
* @see #getAlignmentX()
@@ -4991,7 +4993,7 @@ public abstract class Component
*/
protected String paramString()
{
- StringBuffer param = new StringBuffer();
+ CPStringBuilder param = new CPStringBuilder();
String name = getName();
if (name != null)
param.append(name).append(",");
diff --git a/libjava/classpath/java/awt/Container.java b/libjava/classpath/java/awt/Container.java
index 1e5004048a7..2634735118a 100644
--- a/libjava/classpath/java/awt/Container.java
+++ b/libjava/classpath/java/awt/Container.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.awt;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.HierarchyEvent;
@@ -1341,7 +1343,7 @@ public class Container extends Component
if (layoutMgr == null)
return super.paramString();
- StringBuffer sb = new StringBuffer();
+ CPStringBuilder sb = new CPStringBuilder();
sb.append(super.paramString());
sb.append(",layout=");
sb.append(layoutMgr.getClass().getName());
diff --git a/libjava/classpath/java/awt/JobAttributes.java b/libjava/classpath/java/awt/JobAttributes.java
index 2acb3a01ed3..9ffc048782c 100644
--- a/libjava/classpath/java/awt/JobAttributes.java
+++ b/libjava/classpath/java/awt/JobAttributes.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt;
+import gnu.java.lang.CPStringBuilder;
+
/**
* Needs documentation...
*
@@ -479,7 +481,7 @@ public final class JobAttributes implements Cloneable
public String toString()
{
- StringBuffer s = new StringBuffer("copies=").append(copies)
+ CPStringBuilder s = new CPStringBuilder("copies=").append(copies)
.append(",defaultSelection=").append(selection).append(",destination=")
.append(destination).append(",dialog=").append(dialog)
.append(",fileName=").append(filename).append(",fromPage=")
diff --git a/libjava/classpath/java/awt/MouseInfo.java b/libjava/classpath/java/awt/MouseInfo.java
index 957b6bccbef..8a853e15346 100644
--- a/libjava/classpath/java/awt/MouseInfo.java
+++ b/libjava/classpath/java/awt/MouseInfo.java
@@ -51,6 +51,13 @@ public class MouseInfo
private static MouseInfoPeer peer;
/**
+ * Private constructor to prevent instance creation.
+ */
+ private MouseInfo()
+ {
+ }
+
+ /**
* Returns a PointerInfo object containing information about the current
* location of the mouse pointer
*
diff --git a/libjava/classpath/java/awt/datatransfer/MimeType.java b/libjava/classpath/java/awt/datatransfer/MimeType.java
index 438d78e9e73..8d2dcc01d1e 100644
--- a/libjava/classpath/java/awt/datatransfer/MimeType.java
+++ b/libjava/classpath/java/awt/datatransfer/MimeType.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.datatransfer;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
@@ -224,7 +226,7 @@ class MimeType
*/
public String toString()
{
- StringBuilder s = new StringBuilder();
+ CPStringBuilder s = new CPStringBuilder();
s.append(primaryType);
s.append('/');
s.append(subType);
diff --git a/libjava/classpath/java/awt/event/ActionEvent.java b/libjava/classpath/java/awt/event/ActionEvent.java
index 4bce7d45ce0..937d2cf5363 100644
--- a/libjava/classpath/java/awt/event/ActionEvent.java
+++ b/libjava/classpath/java/awt/event/ActionEvent.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.event;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.AWTEvent;
import java.awt.EventQueue;
@@ -202,9 +204,9 @@ public class ActionEvent extends AWTEvent
*/
public String paramString()
{
- StringBuffer s = new StringBuffer(id == ACTION_PERFORMED
- ? "ACTION_PERFORMED,cmd="
- : "unknown type,cmd=");
+ CPStringBuilder s = new CPStringBuilder(id == ACTION_PERFORMED
+ ? "ACTION_PERFORMED,cmd="
+ : "unknown type,cmd=");
s.append(actionCommand).append(",when=").append(when).append(",modifiers");
int len = s.length();
s.setLength(len + 1);
diff --git a/libjava/classpath/java/awt/event/ComponentEvent.java b/libjava/classpath/java/awt/event/ComponentEvent.java
index 6d478055aa5..156a3e2ad45 100644
--- a/libjava/classpath/java/awt/event/ComponentEvent.java
+++ b/libjava/classpath/java/awt/event/ComponentEvent.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.event;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.AWTEvent;
import java.awt.Component;
@@ -114,7 +116,7 @@ public class ComponentEvent extends AWTEvent
*/
public String paramString()
{
- StringBuffer s = new StringBuffer();
+ CPStringBuilder s = new CPStringBuilder();
// Unlike Sun, we don't throw NullPointerException or ClassCastException
// when source was illegally changed.
diff --git a/libjava/classpath/java/awt/event/HierarchyEvent.java b/libjava/classpath/java/awt/event/HierarchyEvent.java
index e10cefbefcb..3237978f955 100644
--- a/libjava/classpath/java/awt/event/HierarchyEvent.java
+++ b/libjava/classpath/java/awt/event/HierarchyEvent.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.event;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Container;
@@ -226,7 +228,7 @@ public class HierarchyEvent extends AWTEvent
*/
public String paramString()
{
- StringBuffer r = new StringBuffer();
+ CPStringBuilder r = new CPStringBuilder();
switch (id)
{
case HIERARCHY_CHANGED:
diff --git a/libjava/classpath/java/awt/event/InputEvent.java b/libjava/classpath/java/awt/event/InputEvent.java
index 28cd9018599..b9dad3278bd 100644
--- a/libjava/classpath/java/awt/event/InputEvent.java
+++ b/libjava/classpath/java/awt/event/InputEvent.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package java.awt.event;
import gnu.java.awt.EventModifier;
+import gnu.java.lang.CPStringBuilder;
import java.awt.Component;
@@ -376,7 +377,7 @@ public abstract class InputEvent extends ComponentEvent
modifiers &= EventModifier.NEW_MASK;
if (modifiers == 0)
return "";
- StringBuffer s = new StringBuffer();
+ CPStringBuilder s = new CPStringBuilder();
if ((modifiers & META_DOWN_MASK) != 0)
s.append("Meta+");
if ((modifiers & CTRL_DOWN_MASK) != 0)
diff --git a/libjava/classpath/java/awt/event/InputMethodEvent.java b/libjava/classpath/java/awt/event/InputMethodEvent.java
index f6711a8fa5a..e0be40d5a67 100644
--- a/libjava/classpath/java/awt/event/InputMethodEvent.java
+++ b/libjava/classpath/java/awt/event/InputMethodEvent.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.event;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.EventQueue;
@@ -257,8 +259,8 @@ public class InputMethodEvent extends AWTEvent
*/
public String paramString()
{
- StringBuffer s
- = new StringBuffer(80 + (text == null ? 0
+ CPStringBuilder s
+ = new CPStringBuilder(80 + (text == null ? 0
: text.getEndIndex() - text.getBeginIndex()));
s.append(id == INPUT_METHOD_TEXT_CHANGED ? "INPUT_METHOD_TEXT_CHANGED, "
: "CARET_POSITION_CHANGED, ");
diff --git a/libjava/classpath/java/awt/event/KeyEvent.java b/libjava/classpath/java/awt/event/KeyEvent.java
index 42084d7333e..bb7ed4c2dc7 100644
--- a/libjava/classpath/java/awt/event/KeyEvent.java
+++ b/libjava/classpath/java/awt/event/KeyEvent.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package java.awt.event;
import gnu.java.awt.EventModifier;
+import gnu.java.lang.CPStringBuilder;
import java.awt.Component;
import java.io.IOException;
@@ -1673,7 +1674,7 @@ public class KeyEvent extends InputEvent
*/
public String paramString()
{
- StringBuffer s = new StringBuffer();
+ CPStringBuilder s = new CPStringBuilder();
switch (id)
{
diff --git a/libjava/classpath/java/awt/event/MouseEvent.java b/libjava/classpath/java/awt/event/MouseEvent.java
index 0ca833604a6..86a584c4103 100644
--- a/libjava/classpath/java/awt/event/MouseEvent.java
+++ b/libjava/classpath/java/awt/event/MouseEvent.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package java.awt.event;
import gnu.java.awt.EventModifier;
+import gnu.java.lang.CPStringBuilder;
import java.awt.Component;
import java.awt.Point;
@@ -434,7 +435,7 @@ public class MouseEvent extends InputEvent
*/
public String paramString()
{
- StringBuffer s = new StringBuffer();
+ CPStringBuilder s = new CPStringBuilder();
switch (id)
{
case MOUSE_CLICKED:
diff --git a/libjava/classpath/java/awt/event/WindowEvent.java b/libjava/classpath/java/awt/event/WindowEvent.java
index 2186889e601..1298e1ad8ba 100644
--- a/libjava/classpath/java/awt/event/WindowEvent.java
+++ b/libjava/classpath/java/awt/event/WindowEvent.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.event;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.Frame;
import java.awt.Window;
@@ -270,7 +272,7 @@ public class WindowEvent extends ComponentEvent
*/
public String paramString()
{
- StringBuffer s = new StringBuffer();
+ CPStringBuilder s = new CPStringBuilder();
switch (id)
{
case WINDOW_OPENED:
diff --git a/libjava/classpath/java/awt/font/TextLayout.java b/libjava/classpath/java/awt/font/TextLayout.java
index dc0e537eba9..4346ab91d53 100644
--- a/libjava/classpath/java/awt/font/TextLayout.java
+++ b/libjava/classpath/java/awt/font/TextLayout.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.font;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
@@ -362,7 +364,7 @@ public final class TextLayout implements Cloneable
private static String getText(AttributedCharacterIterator iter)
{
- StringBuffer sb = new StringBuffer();
+ CPStringBuilder sb = new CPStringBuilder();
int idx = iter.getIndex();
for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next())
sb.append(c);
diff --git a/libjava/classpath/java/awt/image/BandedSampleModel.java b/libjava/classpath/java/awt/image/BandedSampleModel.java
index afe62bdc4bd..94dbd8d4669 100644
--- a/libjava/classpath/java/awt/image/BandedSampleModel.java
+++ b/libjava/classpath/java/awt/image/BandedSampleModel.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.awt.image;
import gnu.java.awt.Buffers;
+import gnu.java.lang.CPStringBuilder;
/**
* A sample model that reads each sample value from a separate band in the
@@ -742,7 +743,7 @@ public final class BandedSampleModel extends ComponentSampleModel
*/
public String toString()
{
- StringBuffer result = new StringBuffer();
+ CPStringBuilder result = new CPStringBuilder();
result.append(getClass().getName());
result.append("[");
result.append("scanlineStride=").append(scanlineStride);
diff --git a/libjava/classpath/java/awt/image/BufferedImage.java b/libjava/classpath/java/awt/image/BufferedImage.java
index 78623ccd928..260d254fd65 100644
--- a/libjava/classpath/java/awt/image/BufferedImage.java
+++ b/libjava/classpath/java/awt/image/BufferedImage.java
@@ -41,6 +41,8 @@ package java.awt.image;
import gnu.java.awt.Buffers;
import gnu.java.awt.ClasspathGraphicsEnvironment;
import gnu.java.awt.ComponentDataBlitOp;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
@@ -778,9 +780,9 @@ public class BufferedImage extends Image
public String toString()
{
- StringBuffer buf;
+ CPStringBuilder buf;
- buf = new StringBuffer(/* estimated length */ 120);
+ buf = new CPStringBuilder(/* estimated length */ 120);
buf.append("BufferedImage@");
buf.append(Integer.toHexString(hashCode()));
buf.append(": type=");
diff --git a/libjava/classpath/java/awt/image/ColorModel.java b/libjava/classpath/java/awt/image/ColorModel.java
index e2873c5d71f..005b8d45ffe 100644
--- a/libjava/classpath/java/awt/image/ColorModel.java
+++ b/libjava/classpath/java/awt/image/ColorModel.java
@@ -631,8 +631,8 @@ public abstract class ColorModel implements Transparency
throw new UnsupportedOperationException();
}
- protected void coerceDataWorker(WritableRaster raster,
- boolean isAlphaPremultiplied)
+ void coerceDataWorker(WritableRaster raster,
+ boolean isAlphaPremultiplied)
{
int w = raster.getWidth();
int h = raster.getHeight();
diff --git a/libjava/classpath/java/awt/image/ComponentColorModel.java b/libjava/classpath/java/awt/image/ComponentColorModel.java
index 2096800b20d..e1e85e1912a 100644
--- a/libjava/classpath/java/awt/image/ComponentColorModel.java
+++ b/libjava/classpath/java/awt/image/ComponentColorModel.java
@@ -312,7 +312,7 @@ public class ComponentColorModel extends ColorModel
/* TODO: provide better implementation based on the
assumptions we can make due to the specific type of the
color model. */
- super.coerceDataWorker(raster, isAlphaPremultiplied);
+ coerceDataWorker(raster, isAlphaPremultiplied);
return new ComponentColorModel(cspace, hasAlpha, isAlphaPremultiplied,
transparency, transferType);
diff --git a/libjava/classpath/java/awt/image/DirectColorModel.java b/libjava/classpath/java/awt/image/DirectColorModel.java
index dab15319fce..3d43c764237 100644
--- a/libjava/classpath/java/awt/image/DirectColorModel.java
+++ b/libjava/classpath/java/awt/image/DirectColorModel.java
@@ -393,8 +393,8 @@ public class DirectColorModel extends PackedColorModel
return Buffers.getData(buffer);
}
- public ColorModel coerceData (WritableRaster raster,
- boolean isAlphaPremultiplied)
+ public final ColorModel coerceData (WritableRaster raster,
+ boolean isAlphaPremultiplied)
{
if (this.isAlphaPremultiplied == isAlphaPremultiplied || !hasAlpha())
return this;
@@ -402,7 +402,7 @@ public class DirectColorModel extends PackedColorModel
/* TODO: provide better implementation based on the
assumptions we can make due to the specific type of the
color model. */
- super.coerceDataWorker(raster, isAlphaPremultiplied);
+ coerceDataWorker(raster, isAlphaPremultiplied);
return new DirectColorModel(cspace, pixel_bits, getRedMask(),
getGreenMask(), getBlueMask(), getAlphaMask(),
diff --git a/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java b/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
index 8732e57659e..8db26b52d42 100644
--- a/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
+++ b/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.awt.image;
import gnu.java.awt.Buffers;
+import gnu.java.lang.CPStringBuilder;
/**
* MultiPixelPackedSampleModel provides a single band model that supports
@@ -587,7 +588,7 @@ public class MultiPixelPackedSampleModel extends SampleModel
*/
public String toString()
{
- StringBuffer result = new StringBuffer();
+ CPStringBuilder result = new CPStringBuilder();
result.append(getClass().getName());
result.append("[");
result.append("scanlineStride=").append(scanlineStride);
diff --git a/libjava/classpath/java/awt/image/Raster.java b/libjava/classpath/java/awt/image/Raster.java
index fb0950dabf3..615155fb3f9 100644
--- a/libjava/classpath/java/awt/image/Raster.java
+++ b/libjava/classpath/java/awt/image/Raster.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.awt.image;
+import gnu.java.lang.CPStringBuilder;
+
import java.awt.Point;
import java.awt.Rectangle;
@@ -920,7 +922,7 @@ public class Raster
*/
public String toString()
{
- StringBuffer result = new StringBuffer();
+ CPStringBuilder result = new CPStringBuilder();
result.append(getClass().getName());
result.append("[(");
diff --git a/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java b/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
index 1b0ac3f7904..22513865197 100644
--- a/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
+++ b/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
@@ -39,6 +39,7 @@ package java.awt.image;
import java.util.Arrays;
import gnu.java.awt.BitMaskExtent;
+import gnu.java.lang.CPStringBuilder;
/**
* A <code>SampleModel</code> used when all samples are stored in a single
@@ -569,7 +570,7 @@ public class SinglePixelPackedSampleModel extends SampleModel
*/
public String toString()
{
- StringBuffer result = new StringBuffer();
+ CPStringBuilder result = new CPStringBuilder();
result.append(getClass().getName());
result.append("[");
result.append("scanlineStride=").append(scanlineStride);
diff --git a/libjava/classpath/java/awt/image/WritableRaster.java b/libjava/classpath/java/awt/image/WritableRaster.java
index bf8db140c7f..02789a3d142 100644
--- a/libjava/classpath/java/awt/image/WritableRaster.java
+++ b/libjava/classpath/java/awt/image/WritableRaster.java
@@ -111,13 +111,8 @@ public class WritableRaster extends Raster
public WritableRaster createWritableTranslatedChild(int childMinX,
int childMinY)
{
- // This mirrors the code from the super class
- int tcx = sampleModelTranslateX - minX + childMinX;
- int tcy = sampleModelTranslateY - minY + childMinY;
-
- return new WritableRaster(sampleModel, dataBuffer,
- new Rectangle(childMinX, childMinY, width, height),
- new Point(tcx, tcy), this);
+ return createWritableChild(minX, minY, width, height,
+ childMinX, childMinY, null);
}
/**
@@ -143,12 +138,14 @@ public class WritableRaster extends Raster
SampleModel sm = (bandList == null) ?
sampleModel :
sampleModel.createSubsetSampleModel(bandList);
-
- return new WritableRaster(sm, dataBuffer,
- new Rectangle(childMinX, childMinY, w, h),
- new Point(sampleModelTranslateX + childMinX - parentX,
- sampleModelTranslateY + childMinY - parentY),
- this);
+
+ return new WritableRaster(sm, getDataBuffer(),
+ new Rectangle(childMinX, childMinY, w, h),
+ new Point(sampleModelTranslateX + childMinX -
+ parentX,
+ sampleModelTranslateY + childMinY -
+ parentY),
+ this);
}
public Raster createChild(int parentX, int parentY, int width,
diff --git a/libjava/classpath/java/beans/Statement.java b/libjava/classpath/java/beans/Statement.java
index 0a01798adc2..5ecba37c87d 100644
--- a/libjava/classpath/java/beans/Statement.java
+++ b/libjava/classpath/java/beans/Statement.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.beans;
+import gnu.java.lang.CPStringBuilder;
+
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@@ -353,7 +355,7 @@ public class Statement
*/
public String toString()
{
- StringBuffer result = new StringBuffer();
+ CPStringBuilder result = new CPStringBuilder();
String targetName;
if (target != null)
diff --git a/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java b/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java
index 1c27f98e57b..725c2d46888 100644
--- a/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java
+++ b/libjava/classpath/java/beans/beancontext/BeanContextServicesSupport.java
@@ -86,6 +86,11 @@ public class BeanContextServicesSupport
private BeanContextServiceProvider provider;
+ BCSSProxyServiceProvider(BeanContextServiceProvider p)
+ {
+ provider = p;
+ }
+
public Iterator getCurrentServiceSelectors (BeanContextServices bcs,
Class serviceClass)
{
diff --git a/libjava/classpath/java/io/BufferedReader.java b/libjava/classpath/java/io/BufferedReader.java
index c52d15ec60c..3dbe80b77fb 100644
--- a/libjava/classpath/java/io/BufferedReader.java
+++ b/libjava/classpath/java/io/BufferedReader.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.io;
+import gnu.java.lang.CPStringBuilder;
+
/* Written using "Java Class Libraries", 2nd edition, plus online
* API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
@@ -450,7 +452,7 @@ public class BufferedReader extends Reader
pos++;
return str;
}
- StringBuilder sbuf = new StringBuilder(200);
+ CPStringBuilder sbuf = new CPStringBuilder(200);
sbuf.append(buffer, pos, i - pos);
pos = i;
// We only want to return null when no characters were read before
diff --git a/libjava/classpath/java/io/DataInputStream.java b/libjava/classpath/java/io/DataInputStream.java
index ad43498c8d7..51cf51a8e2a 100644
--- a/libjava/classpath/java/io/DataInputStream.java
+++ b/libjava/classpath/java/io/DataInputStream.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.io;
+import gnu.java.lang.CPStringBuilder;
+
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
@@ -350,7 +352,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
*/
public final String readLine() throws IOException
{
- StringBuilder strb = new StringBuilder();
+ CPStringBuilder strb = new CPStringBuilder();
while (true)
{
@@ -747,7 +749,7 @@ public class DataInputStream extends FilterInputStream implements DataInput
{
// Give StringBuffer an initial estimated size to avoid
// enlarge buffer frequently
- StringBuilder strbuf = new StringBuilder (buf.length / 2 + 2);
+ CPStringBuilder strbuf = new CPStringBuilder (buf.length / 2 + 2);
for (int i = 0; i < buf.length; )
{
diff --git a/libjava/classpath/java/io/File.java b/libjava/classpath/java/io/File.java
index cd11163509b..f023310449f 100644
--- a/libjava/classpath/java/io/File.java
+++ b/libjava/classpath/java/io/File.java
@@ -41,6 +41,8 @@ package java.io;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
+
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -158,7 +160,7 @@ public class File implements Serializable, Comparable<File>
return false;
if (VMFile.isDirectory(path))
- return VMFile.canWriteDirectory(this);
+ return VMFile.canWriteDirectory(path);
else
return VMFile.canWrite(path);
}
@@ -317,7 +319,7 @@ public class File implements Serializable, Comparable<File>
return p;
}
- StringBuffer newpath = new StringBuffer(plen);
+ CPStringBuilder newpath = new CPStringBuilder(plen);
int last = 0;
while (dupIndex != -1)
{
diff --git a/libjava/classpath/java/io/StreamTokenizer.java b/libjava/classpath/java/io/StreamTokenizer.java
index 759aa9a2f05..87384f39f3a 100644
--- a/libjava/classpath/java/io/StreamTokenizer.java
+++ b/libjava/classpath/java/io/StreamTokenizer.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.io;
+import gnu.java.lang.CPStringBuilder;
+
/**
* This class parses streams of characters into tokens. There are a
* million-zillion flags that can be set to control the parsing, as
@@ -391,7 +393,7 @@ public class StreamTokenizer
}
}
- StringBuffer tokbuf = new StringBuffer();
+ CPStringBuilder tokbuf = new CPStringBuilder();
tokbuf.append((char) ch);
int decCount = 0;
@@ -417,7 +419,7 @@ public class StreamTokenizer
}
else if (isAlphabetic(ch))
{
- StringBuffer tokbuf = new StringBuffer();
+ CPStringBuilder tokbuf = new CPStringBuilder();
tokbuf.append((char) ch);
while (isAlphabetic(ch = in.read()) || isNumeric(ch))
tokbuf.append((char) ch);
@@ -440,7 +442,7 @@ public class StreamTokenizer
else if (isQuote(ch))
{
ttype = ch;
- StringBuffer tokbuf = new StringBuffer();
+ CPStringBuilder tokbuf = new CPStringBuilder();
while ((ch = in.read()) != ttype && ch != '\n' && ch != '\r' &&
ch != TT_EOF)
{
diff --git a/libjava/classpath/java/lang/AbstractStringBuffer.java b/libjava/classpath/java/lang/AbstractStringBuffer.java
new file mode 100644
index 00000000000..dc3a8c9ecda
--- /dev/null
+++ b/libjava/classpath/java/lang/AbstractStringBuffer.java
@@ -0,0 +1,1037 @@
+/* AbstractStringBuffer.java -- Growable strings
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * This class is based on gnu.classpath.ClasspathStringBuffer but
+ * is package-private to java.lang so it can be used as the basis
+ * for StringBuffer and StringBuilder.
+ * If you modify this, please consider also modifying that code.
+ */
+abstract class AbstractStringBuffer
+ implements Serializable, CharSequence, Appendable
+{
+
+ /**
+ * Index of next available character (and thus the size of the current
+ * string contents). Note that this has permissions set this way so that
+ * String can get the value.
+ *
+ * @serial the number of characters in the buffer
+ */
+ int count;
+
+ /**
+ * The buffer. Note that this has permissions set this way so that String
+ * can get the value.
+ *
+ * @serial the buffer
+ */
+ char[] value;
+
+ /**
+ * The default capacity of a buffer.
+ */
+ private static final int DEFAULT_CAPACITY = 16;
+
+ /**
+ * Create a new AbstractStringBuffer with default capacity 16.
+ */
+ AbstractStringBuffer()
+ {
+ this(DEFAULT_CAPACITY);
+ }
+
+ /**
+ * Create an empty <code>StringBuffer</code> with the specified initial
+ * capacity.
+ *
+ * @param capacity the initial capacity
+ * @throws NegativeArraySizeException if capacity is negative
+ */
+ AbstractStringBuffer(int capacity)
+ {
+ value = new char[capacity];
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters in the
+ * specified <code>String</code>. Initial capacity will be the size of the
+ * String plus 16.
+ *
+ * @param str the <code>String</code> to convert
+ * @throws NullPointerException if str is null
+ */
+ AbstractStringBuffer(String str)
+ {
+ count = str.count;
+ value = new char[count + DEFAULT_CAPACITY];
+ str.getChars(0, count, value, 0);
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters in the
+ * specified <code>CharSequence</code>. Initial capacity will be the
+ * length of the sequence plus 16; if the sequence reports a length
+ * less than or equal to 0, then the initial capacity will be 16.
+ *
+ * @param seq the initializing <code>CharSequence</code>
+ * @throws NullPointerException if str is null
+ * @since 1.5
+ */
+ AbstractStringBuffer(CharSequence seq)
+ {
+ int len = seq.length();
+ count = len <= 0 ? 0 : len;
+ value = new char[count + DEFAULT_CAPACITY];
+ for (int i = 0; i < len; ++i)
+ value[i] = seq.charAt(i);
+ }
+
+ /**
+ * Increase the capacity of this <code>StringBuffer</code>. This will
+ * ensure that an expensive growing operation will not occur until
+ * <code>minimumCapacity</code> is reached. The buffer is grown to the
+ * larger of <code>minimumCapacity</code> and
+ * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+ *
+ * @param minimumCapacity the new capacity
+ * @see #capacity()
+ */
+ public void ensureCapacity(int minimumCapacity)
+ {
+ ensureCapacity_unsynchronized(minimumCapacity);
+ }
+
+ /**
+ * Set the length of this StringBuffer. If the new length is greater than
+ * the current length, all the new characters are set to '\0'. If the new
+ * length is less than the current length, the first <code>newLength</code>
+ * characters of the old array will be preserved, and the remaining
+ * characters are truncated.
+ *
+ * @param newLength the new length
+ * @throws IndexOutOfBoundsException if the new length is negative
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #length()
+ */
+ public void setLength(int newLength)
+ {
+ if (newLength < 0)
+ throw new StringIndexOutOfBoundsException(newLength);
+
+ int valueLength = value.length;
+
+ /* Always call ensureCapacity_unsynchronized in order to preserve
+ copy-on-write semantics. */
+ ensureCapacity_unsynchronized(newLength);
+
+ if (newLength < valueLength)
+ {
+ /* If the StringBuffer's value just grew, then we know that
+ value is newly allocated and the region between count and
+ newLength is filled with '\0'. */
+ count = newLength;
+ }
+ else
+ {
+ /* The StringBuffer's value doesn't need to grow. However,
+ we should clear out any cruft that may exist. */
+ while (count < newLength)
+ value[count++] = '\0';
+ }
+ }
+
+ /**
+ * Get the character at the specified index.
+ *
+ * @param index the index of the character to get, starting at 0
+ * @return the character at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public char charAt(int index)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ return value[index];
+ }
+
+ /**
+ * Get the code point at the specified index. This is like #charAt(int),
+ * but if the character is the start of a surrogate pair, and the
+ * following character completes the pair, then the corresponding
+ * supplementary code point is returned.
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public int codePointAt(int index)
+ {
+ return Character.codePointAt(value, index, count);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(int), but checks the characters at <code>index-1</code> and
+ * <code>index-2</code> to see if they form a supplementary code point.
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public int codePointBefore(int index)
+ {
+ // Character.codePointBefore() doesn't perform this check. We
+ // could use the CharSequence overload, but this is just as easy.
+ if (index >= count)
+ throw new IndexOutOfBoundsException();
+ return Character.codePointBefore(value, index, 1);
+ }
+
+ /**
+ * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+ * characters will be copied into the array you pass in.
+ *
+ * @param srcOffset the index to start copying from (inclusive)
+ * @param srcEnd the index to stop copying from (exclusive)
+ * @param dst the array to copy into
+ * @param dstOffset the index to start copying into
+ * @throws NullPointerException if dst is null
+ * @throws IndexOutOfBoundsException if any source or target indices are
+ * out of range (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dest problems cause an
+ * ArrayIndexOutOfBoundsException)
+ * @see System#arraycopy(Object, int, Object, int, int)
+ */
+ public void getChars(int srcOffset, int srcEnd,
+ char[] dst, int dstOffset)
+ {
+ if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
+ throw new StringIndexOutOfBoundsException();
+ VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+ }
+
+ /**
+ * Set the character at the specified index.
+ *
+ * @param index the index of the character to set starting at 0
+ * @param ch the value to set that character to
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public void setCharAt(int index, char ch)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity_unsynchronized(count);
+ value[index] = ch;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param obj the <code>Object</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(Object)
+ * @see #append(String)
+ */
+ public AbstractStringBuffer append(Object obj)
+ {
+ return append(String.valueOf(obj));
+ }
+
+ /**
+ * Append the <code>String</code> to this <code>StringBuffer</code>. If
+ * str is null, the String "null" is appended.
+ *
+ * @param str the <code>String</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public AbstractStringBuffer append(String str)
+ {
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity_unsynchronized(count + len);
+ str.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Append the <code>StringBuilder</code> value of the argument to this
+ * <code>StringBuilder</code>. This behaves the same as
+ * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+ *
+ * @param stringBuffer the <code>StringBuilder</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see #append(Object)
+ */
+ public AbstractStringBuffer append(StringBuffer stringBuffer)
+ {
+ if (stringBuffer == null)
+ return append("null");
+ synchronized (stringBuffer)
+ {
+ int len = stringBuffer.count;
+ ensureCapacity(count + len);
+ VMSystem.arraycopy(stringBuffer.value, 0, value, count, len);
+ count += len;
+ }
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> array to this <code>StringBuffer</code>.
+ * This is similar (but more efficient) than
+ * <code>append(new String(data))</code>, except in the case of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @see #append(char[], int, int)
+ */
+ public AbstractStringBuffer append(char[] data)
+ {
+ return append(data, 0, data.length);
+ }
+
+ /**
+ * Append part of the <code>char</code> array to this
+ * <code>StringBuffer</code>. This is similar (but more efficient) than
+ * <code>append(new String(data, offset, count))</code>, except in the case
+ * of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @param offset the start location in <code>str</code>
+ * @param count the number of characters to get from <code>str</code>
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if offset or count is out of range
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public AbstractStringBuffer append(char[] data, int offset, int count)
+ {
+ if (offset < 0 || count < 0 || offset > data.length - count)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity_unsynchronized(this.count + count);
+ VMSystem.arraycopy(data, offset, value, this.count, count);
+ this.count += count;
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param bool the <code>boolean</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(boolean)
+ */
+ public AbstractStringBuffer append(boolean bool)
+ {
+ return append(bool ? "true" : "false");
+ }
+
+ /**
+ * Append the <code>char</code> to this <code>StringBuffer</code>.
+ *
+ * @param ch the <code>char</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public AbstractStringBuffer append(char ch)
+ {
+ ensureCapacity_unsynchronized(count + 1);
+ value[count++] = ch;
+ return this;
+ }
+
+ /**
+ * Append the characters in the <code>CharSequence</code> to this
+ * buffer.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @return this <code>StringBuffer</code>
+ * @since 1.5
+ */
+ public AbstractStringBuffer append(CharSequence seq)
+ {
+ return append(seq, 0, seq.length());
+ }
+
+ /**
+ * Append some characters from the <code>CharSequence</code> to this
+ * buffer. If the argument is null, the <code>seq</code> is assumed
+ * to be equal to the string <code>"null"</code>.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @param start the starting index
+ * @param end one past the final index
+ * @return this <code>StringBuffer</code>
+ * @since 1.5
+ */
+ public AbstractStringBuffer append(CharSequence seq, int start, int end)
+ {
+ if (seq == null)
+ seq = "null";
+ if (end - start > 0)
+ {
+ ensureCapacity_unsynchronized(count + end - start);
+ for (; start < end; ++start)
+ value[count++] = seq.charAt(start);
+ }
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param inum the <code>int</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(int)
+ */
+ // This is native in libgcj, for efficiency.
+ public AbstractStringBuffer append(int inum)
+ {
+ return append(String.valueOf(inum));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param lnum the <code>long</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(long)
+ */
+ public AbstractStringBuffer append(long lnum)
+ {
+ return append(Long.toString(lnum, 10));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param fnum the <code>float</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(float)
+ */
+ public AbstractStringBuffer append(float fnum)
+ {
+ return append(Float.toString(fnum));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param dnum the <code>double</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(double)
+ */
+ public AbstractStringBuffer append(double dnum)
+ {
+ return append(Double.toString(dnum));
+ }
+
+ /**
+ * Append the code point to this <code>StringBuffer</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuffer</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public AbstractStringBuffer appendCodePoint(int code)
+ {
+ int len = Character.charCount(code);
+ ensureCapacity_unsynchronized(count + len);
+ Character.toChars(code, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Delete characters from this <code>StringBuffer</code>.
+ * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+ * harmless for end to be larger than length().
+ *
+ * @param start the first character to delete
+ * @param end the index after the last character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @since 1.2
+ */
+ public AbstractStringBuffer delete(int start, int end)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+ if (end > count)
+ end = count;
+ ensureCapacity_unsynchronized(count);
+ if (count - end != 0)
+ VMSystem.arraycopy(value, end, value, start, count - end);
+ count -= end - start;
+ return this;
+ }
+
+ /**
+ * Delete a character from this <code>StringBuffer</code>.
+ *
+ * @param index the index of the character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if index is out of bounds
+ * @since 1.2
+ */
+ public AbstractStringBuffer deleteCharAt(int index)
+ {
+ return delete(index, index + 1);
+ }
+
+ /**
+ * Replace characters between index <code>start</code> (inclusive) and
+ * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+ * is larger than the size of this StringBuffer, all characters after
+ * <code>start</code> are replaced.
+ *
+ * @param start the beginning index of characters to delete (inclusive)
+ * @param end the ending index of characters to delete (exclusive)
+ * @param str the new <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @throws NullPointerException if str is null
+ * @since 1.2
+ */
+ public AbstractStringBuffer replace(int start, int end, String str)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+
+ int len = str.count;
+ // Calculate the difference in 'count' after the replace.
+ int delta = len - (end > count ? count : end) + start;
+ ensureCapacity_unsynchronized(count + delta);
+
+ if (delta != 0 && end < count)
+ VMSystem.arraycopy(value, end, value, end + delta, count - end);
+
+ str.getChars(0, len, value, start);
+ count += delta;
+ return this;
+ }
+
+ /**
+ * Insert a subarray of the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>char[]</code> to insert
+ * @param str_offset the index in <code>str</code> to start inserting from
+ * @param len the number of characters to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if any index is out of bounds
+ * @since 1.2
+ */
+ public AbstractStringBuffer insert(int offset, char[] str, int str_offset, int len)
+ {
+ if (offset < 0 || offset > count || len < 0
+ || str_offset < 0 || str_offset > str.length - len)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity_unsynchronized(count + len);
+ VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
+ VMSystem.arraycopy(str, str_offset, value, offset, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param obj the <code>Object</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @exception StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(Object)
+ */
+ public AbstractStringBuffer insert(int offset, Object obj)
+ {
+ return insert(offset, obj == null ? "null" : obj.toString());
+ }
+
+ /**
+ * Insert the <code>String</code> argument into this
+ * <code>StringBuffer</code>. If str is null, the String "null" is used
+ * instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public AbstractStringBuffer insert(int offset, String str)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity_unsynchronized(count + len);
+ VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
+ str.getChars(0, len, value, offset);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset is out of bounds
+ * @since 1.5
+ */
+ public AbstractStringBuffer insert(int offset, CharSequence sequence)
+ {
+ if (sequence == null)
+ sequence = "null";
+ return insert(offset, sequence, 0, sequence.length());
+ }
+
+ /**
+ * Insert a subsequence of the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @param start the starting index of the subsequence
+ * @param end one past the ending index of the subsequence
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset, start,
+ * or end are out of bounds
+ * @since 1.5
+ */
+ public AbstractStringBuffer insert(int offset, CharSequence sequence, int start, int end)
+ {
+ if (sequence == null)
+ sequence = "null";
+ if (start < 0 || end < 0 || start > end || end > sequence.length())
+ throw new IndexOutOfBoundsException();
+ int len = end - start;
+ ensureCapacity_unsynchronized(count + len);
+ VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
+ for (int i = start; i < end; ++i)
+ value[offset++] = sequence.charAt(i);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param data the <code>char[]</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>data</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see #insert(int, char[], int, int)
+ */
+ public AbstractStringBuffer insert(int offset, char[] data)
+ {
+ return insert(offset, data, 0, data.length);
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param bool the <code>boolean</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(boolean)
+ */
+ public AbstractStringBuffer insert(int offset, boolean bool)
+ {
+ return insert(offset, bool ? "true" : "false");
+ }
+
+ /**
+ * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param ch the <code>char</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public AbstractStringBuffer insert(int offset, char ch)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ ensureCapacity_unsynchronized(count + 1);
+ VMSystem.arraycopy(value, offset, value, offset + 1, count - offset);
+ value[offset] = ch;
+ count++;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param inum the <code>int</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(int)
+ */
+ public AbstractStringBuffer insert(int offset, int inum)
+ {
+ return insert(offset, String.valueOf(inum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param lnum the <code>long</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(long)
+ */
+ public AbstractStringBuffer insert(int offset, long lnum)
+ {
+ return insert(offset, Long.toString(lnum, 10));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param fnum the <code>float</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(float)
+ */
+ public AbstractStringBuffer insert(int offset, float fnum)
+ {
+ return insert(offset, Float.toString(fnum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param dnum the <code>double</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(double)
+ */
+ public AbstractStringBuffer insert(int offset, double dnum)
+ {
+ return insert(offset, Double.toString(dnum));
+ }
+
+ /**
+ * Finds the first instance of a substring in this StringBuilder.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #indexOf(String, int)
+ */
+ public int indexOf(String str)
+ {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Finds the first instance of a String in this StringBuffer, starting at
+ * a given index. If starting index is less than 0, the search starts at
+ * the beginning of this String. If the starting index is greater than the
+ * length of this String, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public int indexOf(String str, int fromIndex)
+ {
+ if (fromIndex < 0)
+ fromIndex = 0;
+ int limit = count - str.count;
+ for ( ; fromIndex <= limit; fromIndex++)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Finds the last instance of a substring in this StringBuffer.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #lastIndexOf(String, int)
+ * @since 1.4
+ */
+ public int lastIndexOf(String str)
+ {
+ return lastIndexOf(str, count - str.count);
+ }
+
+ /**
+ * Finds the last instance of a String in this StringBuffer, starting at a
+ * given index. If starting index is greater than the maximum valid index,
+ * then the search begins at the end of this String. If the starting index
+ * is less than zero, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public int lastIndexOf(String str, int fromIndex)
+ {
+ fromIndex = Math.min(fromIndex, count - str.count);
+ for ( ; fromIndex >= 0; fromIndex--)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Reverse the characters in this StringBuffer. The same sequence of
+ * characters exists, but in the reverse index ordering.
+ *
+ * @return this <code>StringBuffer</code>
+ */
+ public AbstractStringBuffer reverse()
+ {
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity_unsynchronized(count);
+ for (int i = count >> 1, j = count - i; --i >= 0; ++j)
+ {
+ char c = value[i];
+ value[i] = value[j];
+ value[j] = c;
+ }
+ return this;
+ }
+
+ /**
+ * This may reduce the amount of memory used by the StringBuffer,
+ * by resizing the internal array to remove unused space. However,
+ * this method is not required to resize, so this behavior cannot
+ * be relied upon.
+ * @since 1.5
+ */
+ public void trimToSize()
+ {
+ int wouldSave = value.length - count;
+ // Some random heuristics: if we save less than 20 characters, who
+ // cares.
+ if (wouldSave < 20)
+ return;
+ // If we save more than 200 characters, shrink.
+ // If we save more than 1/4 of the buffer, shrink.
+ if (wouldSave > 200 || wouldSave * 4 > value.length)
+ {
+ char[] newValue = new char[count];
+ VMSystem.arraycopy(value, 0, newValue, 0, count);
+ value = newValue;
+ }
+ }
+
+ /**
+ * Return the number of code points between two indices in the
+ * <code>StringBuffer</code>. An unpaired surrogate counts as a
+ * code point for this purpose. Characters outside the indicated
+ * range are not examined, even if the range ends in the middle of a
+ * surrogate pair.
+ *
+ * @param start the starting index
+ * @param end one past the ending index
+ * @return the number of code points
+ * @since 1.5
+ */
+ public int codePointCount(int start, int end)
+ {
+ if (start < 0 || end >= count || start > end)
+ throw new StringIndexOutOfBoundsException();
+
+ int count = 0;
+ while (start < end)
+ {
+ char base = value[start];
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == end
+ || start == count
+ || value[start + 1] < Character.MIN_LOW_SURROGATE
+ || value[start + 1] > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ ++count;
+ }
+ return count;
+ }
+
+ /**
+ * Starting at the given index, this counts forward by the indicated
+ * number of code points, and then returns the resulting index. An
+ * unpaired surrogate counts as a single code point for this
+ * purpose.
+ *
+ * @param start the starting index
+ * @param codePoints the number of code points
+ * @return the resulting index
+ * @since 1.5
+ */
+ public int offsetByCodePoints(int start, int codePoints)
+ {
+ while (codePoints > 0)
+ {
+ char base = value[start];
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == count
+ || value[start + 1] < Character.MIN_LOW_SURROGATE
+ || value[start + 1] > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ --codePoints;
+ }
+ return start;
+ }
+
+ /**
+ * Increase the capacity of this <code>StringBuilder</code>. This will
+ * ensure that an expensive growing operation will not occur until
+ * <code>minimumCapacity</code> is reached. The buffer is grown to the
+ * larger of <code>minimumCapacity</code> and
+ * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+ *
+ * @param minimumCapacity the new capacity
+ * @see #capacity()
+ */
+ void ensureCapacity_unsynchronized(int minimumCapacity)
+ {
+ if (minimumCapacity > value.length)
+ {
+ int max = value.length * 2 + 2;
+ minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+ char[] nb = new char[minimumCapacity];
+ VMSystem.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ }
+ }
+
+ /**
+ * Predicate which determines if a substring of this matches another String
+ * starting at a specified offset for each String and continuing for a
+ * specified length. This is more efficient than creating a String to call
+ * indexOf on.
+ *
+ * @param toffset index to start comparison at for this String
+ * @param other non-null String to compare to region of this
+ * @return true if regions match, false otherwise
+ * @see #indexOf(String, int)
+ * @see #lastIndexOf(String, int)
+ * @see String#regionMatches(boolean, int, String, int, int)
+ */
+ private boolean regionMatches(int toffset, String other)
+ {
+ int len = other.count;
+ int index = other.offset;
+ while (--len >= 0)
+ if (value[toffset++] != other.value[index++])
+ return false;
+ return true;
+ }
+
+}
diff --git a/libjava/classpath/java/lang/Byte.java b/libjava/classpath/java/lang/Byte.java
index 7f53a494b95..a1536e1be1b 100644
--- a/libjava/classpath/java/lang/Byte.java
+++ b/libjava/classpath/java/lang/Byte.java
@@ -88,6 +88,11 @@ public final class Byte extends Number implements Comparable<Byte>
// This caches Byte values, and is used by boxing conversions via
// valueOf(). We're required to cache all possible values here.
private static Byte[] byteCache = new Byte[MAX_VALUE - MIN_VALUE + 1];
+ static
+ {
+ for (int i=MIN_VALUE; i <= MAX_VALUE; i++)
+ byteCache[i - MIN_VALUE] = new Byte((byte) i);
+ }
/**
@@ -185,7 +190,7 @@ public final class Byte extends Number implements Comparable<Byte>
*/
public static Byte valueOf(String s, int radix)
{
- return new Byte(parseByte(s, radix));
+ return valueOf(parseByte(s, radix));
}
/**
@@ -201,7 +206,7 @@ public final class Byte extends Number implements Comparable<Byte>
*/
public static Byte valueOf(String s)
{
- return new Byte(parseByte(s, 10));
+ return valueOf(parseByte(s, 10));
}
/**
@@ -214,12 +219,7 @@ public final class Byte extends Number implements Comparable<Byte>
*/
public static Byte valueOf(byte val)
{
- synchronized (byteCache)
- {
- if (byteCache[val - MIN_VALUE] == null)
- byteCache[val - MIN_VALUE] = new Byte(val);
- return byteCache[val - MIN_VALUE];
- }
+ return byteCache[val - MIN_VALUE];
}
/**
@@ -258,7 +258,7 @@ public final class Byte extends Number implements Comparable<Byte>
int i = Integer.parseInt(s, 10, true);
if ((byte) i != i)
throw new NumberFormatException();
- return new Byte((byte) i);
+ return valueOf((byte) i);
}
/**
diff --git a/libjava/classpath/java/lang/Character.java b/libjava/classpath/java/lang/Character.java
index 506033f31bc..eaa9557f651 100644
--- a/libjava/classpath/java/lang/Character.java
+++ b/libjava/classpath/java/lang/Character.java
@@ -2055,6 +2055,11 @@ public final class Character implements Serializable, Comparable<Character>
// this constant controls how much we actually cache.
private static final int MAX_CACHE = 127;
private static Character[] charCache = new Character[MAX_CACHE + 1];
+ static
+ {
+ for (char i=0; i <= MAX_CACHE; i++)
+ charCache[i] = new Character(i);
+ }
/**
* Lu = Letter, Uppercase (Informative).
@@ -4208,12 +4213,8 @@ public final class Character implements Serializable, Comparable<Character>
{
if (val > MAX_CACHE)
return new Character(val);
- synchronized (charCache)
- {
- if (charCache[val - MIN_VALUE] == null)
- charCache[val - MIN_VALUE] = new Character(val);
- return charCache[val - MIN_VALUE];
- }
+ else
+ return charCache[val - MIN_VALUE];
}
/**
diff --git a/libjava/classpath/java/lang/ClassLoader.java b/libjava/classpath/java/lang/ClassLoader.java
index 3d7c32cc935..591406ac4dc 100644
--- a/libjava/classpath/java/lang/ClassLoader.java
+++ b/libjava/classpath/java/lang/ClassLoader.java
@@ -659,7 +659,7 @@ public abstract class ClassLoader
*/
protected Enumeration<URL> findResources(String name) throws IOException
{
- return (Enumeration<URL>) EmptyEnumeration.getInstance();
+ return new EmptyEnumeration<URL>();
}
/**
diff --git a/libjava/classpath/java/lang/Double.java b/libjava/classpath/java/lang/Double.java
index 466d48205ea..f3f7cb1e0ec 100644
--- a/libjava/classpath/java/lang/Double.java
+++ b/libjava/classpath/java/lang/Double.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package java.lang;
+import gnu.java.lang.CPStringBuilder;
/**
* Instances of class <code>Double</code> represent primitive
@@ -103,6 +104,16 @@ public final class Double extends Number implements Comparable<Double>
public static final Class<Double> TYPE = (Class<Double>) VMClassLoader.getPrimitiveClass('D');
/**
+ * Cache representation of 0
+ */
+ private static final Double ZERO = new Double(0.0d);
+
+ /**
+ * Cache representation of 1
+ */
+ private static final Double ONE = new Double(1.0d);
+
+ /**
* The immutable value of this Double.
*
* @serial the wrapped double
@@ -201,7 +212,7 @@ public final class Double extends Number implements Comparable<Double>
return d < 0 ? "-Infinity" : "Infinity";
long bits = doubleToLongBits(d);
- StringBuilder result = new StringBuilder();
+ CPStringBuilder result = new CPStringBuilder();
if (bits < 0)
result.append('-');
@@ -260,8 +271,12 @@ public final class Double extends Number implements Comparable<Double>
*/
public static Double valueOf(double val)
{
- // We don't actually cache, but we could.
- return new Double(val);
+ if ((val == 0.0) && (doubleToRawLongBits(val) == 0L))
+ return ZERO;
+ else if (val == 1.0)
+ return ONE;
+ else
+ return new Double(val);
}
/**
@@ -276,7 +291,7 @@ public final class Double extends Number implements Comparable<Double>
*/
public static Double valueOf(String s)
{
- return new Double(parseDouble(s));
+ return valueOf(parseDouble(s));
}
/**
@@ -489,17 +504,13 @@ public final class Double extends Number implements Comparable<Double>
*/
public boolean equals(Object obj)
{
- if (! (obj instanceof Double))
- return false;
-
- double d = ((Double) obj).value;
-
- // Avoid call to native method. However, some implementations, like gcj,
- // are better off using floatToIntBits(value) == floatToIntBits(f).
- // Check common case first, then check NaN and 0.
- if (value == d)
- return (value != 0) || (1 / value == 1 / d);
- return isNaN(value) && isNaN(d);
+ if (obj instanceof Double)
+ {
+ double d = ((Double) obj).value;
+ return (doubleToRawLongBits(value) == doubleToRawLongBits(d)) ||
+ (isNaN(value) && isNaN(d));
+ }
+ return false;
}
/**
diff --git a/libjava/classpath/java/lang/Enum.java b/libjava/classpath/java/lang/Enum.java
index fa217bb67a6..da2e40b8e05 100644
--- a/libjava/classpath/java/lang/Enum.java
+++ b/libjava/classpath/java/lang/Enum.java
@@ -89,7 +89,6 @@ public abstract class Enum<T extends Enum<T>>
* @exception IllegalArgumentException when there is no value s in
* the enum etype.
*/
- @SuppressWarnings("unchecked")
public static <S extends Enum<S>> S valueOf(Class<S> etype, String s)
{
if (etype == null || s == null)
@@ -103,7 +102,9 @@ public abstract class Enum<T extends Enum<T>>
if (! f.isEnumConstant())
throw new IllegalArgumentException(s);
Class.setAccessible(f);
- return (S) f.get(null);
+ @SuppressWarnings("unchecked")
+ S val = (S) f.get(null);
+ return val;
}
catch (NoSuchFieldException exception)
{
diff --git a/libjava/classpath/java/lang/Float.java b/libjava/classpath/java/lang/Float.java
index 72f31b57eb4..63e43c257ea 100644
--- a/libjava/classpath/java/lang/Float.java
+++ b/libjava/classpath/java/lang/Float.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.lang;
+import gnu.java.lang.CPStringBuilder;
+
/**
* Instances of class <code>Float</code> represent primitive
* <code>float</code> values.
@@ -102,6 +104,16 @@ public final class Float extends Number implements Comparable<Float>
public static final int SIZE = 32;
/**
+ * Cache representation of 0
+ */
+ private static final Float ZERO = new Float(0.0f);
+
+ /**
+ * Cache representation of 1
+ */
+ private static final Float ONE = new Float(1.0f);
+
+ /**
* The immutable value of this Float.
*
* @serial the wrapped float
@@ -211,7 +223,7 @@ public final class Float extends Number implements Comparable<Float>
return f < 0 ? "-Infinity" : "Infinity";
int bits = floatToIntBits(f);
- StringBuilder result = new StringBuilder();
+ CPStringBuilder result = new CPStringBuilder();
if (bits < 0)
result.append('-');
@@ -273,7 +285,7 @@ public final class Float extends Number implements Comparable<Float>
*/
public static Float valueOf(String s)
{
- return new Float(parseFloat(s));
+ return valueOf(parseFloat(s));
}
/**
@@ -287,8 +299,12 @@ public final class Float extends Number implements Comparable<Float>
*/
public static Float valueOf(float val)
{
- // We don't actually cache, but we could.
- return new Float(val);
+ if ((val == 0.0) && (floatToRawIntBits(val) == 0))
+ return ZERO;
+ else if (val == 1.0)
+ return ONE;
+ else
+ return new Float(val);
}
/**
@@ -498,17 +514,13 @@ public final class Float extends Number implements Comparable<Float>
*/
public boolean equals(Object obj)
{
- if (! (obj instanceof Float))
- return false;
-
- float f = ((Float) obj).value;
-
- // Avoid call to native method. However, some implementations, like gcj,
- // are better off using floatToIntBits(value) == floatToIntBits(f).
- // Check common case first, then check NaN and 0.
- if (value == f)
- return (value != 0) || (1 / value == 1 / f);
- return isNaN(value) && isNaN(f);
+ if (obj instanceof Float)
+ {
+ float f = ((Float) obj).value;
+ return (floatToRawIntBits(value) == floatToRawIntBits(f)) ||
+ (isNaN(value) && isNaN(f));
+ }
+ return false;
}
/**
diff --git a/libjava/classpath/java/lang/InheritableThreadLocal.java b/libjava/classpath/java/lang/InheritableThreadLocal.java
index 2079a4c20ff..07d52b5d08c 100644
--- a/libjava/classpath/java/lang/InheritableThreadLocal.java
+++ b/libjava/classpath/java/lang/InheritableThreadLocal.java
@@ -37,10 +37,6 @@ exception statement from your version. */
package java.lang;
-import gnu.java.util.WeakIdentityHashMap;
-
-import java.util.Iterator;
-
/**
* A ThreadLocal whose value is inherited by child Threads. The value of the
* InheritableThreadLocal associated with the (parent) Thread is copied to
@@ -97,24 +93,6 @@ public class InheritableThreadLocal<T> extends ThreadLocal<T>
{
// The currentThread is the parent of the new thread.
Thread parentThread = Thread.currentThread();
- if (parentThread.locals != null)
- {
- Iterator keys = parentThread.locals.keySet().iterator();
- while (keys.hasNext())
- {
- Object key = keys.next();
- if (key instanceof InheritableThreadLocal)
- {
- InheritableThreadLocal local = (InheritableThreadLocal)key;
- Object parentValue = parentThread.locals.get(key);
- Object childValue = local.childValue(parentValue == sentinel
- ? null : parentValue);
- if (childThread.locals == null)
- childThread.locals = new WeakIdentityHashMap();
- childThread.locals.put(key, (childValue == null
- ? sentinel : childValue));
- }
- }
- }
+ childThread.locals.inherit(parentThread.locals);
}
}
diff --git a/libjava/classpath/java/lang/Integer.java b/libjava/classpath/java/lang/Integer.java
index cbf5274f0fc..e5ca4b3428e 100644
--- a/libjava/classpath/java/lang/Integer.java
+++ b/libjava/classpath/java/lang/Integer.java
@@ -52,6 +52,7 @@ package java.lang;
* @author Eric Blake (ebb9@email.byu.edu)
* @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @author Ian Rogers
* @since 1.0
* @status updated to 1.5
*/
@@ -92,7 +93,12 @@ public final class Integer extends Number implements Comparable<Integer>
// these constants control how much we actually cache.
private static final int MIN_CACHE = -128;
private static final int MAX_CACHE = 127;
- private static Integer[] intCache = new Integer[MAX_CACHE - MIN_CACHE + 1];
+ private static final Integer[] intCache = new Integer[MAX_CACHE - MIN_CACHE + 1];
+ static
+ {
+ for (int i=MIN_CACHE; i <= MAX_CACHE; i++)
+ intCache[i - MIN_CACHE] = new Integer(i);
+ }
/**
* The immutable value of this Integer.
@@ -126,6 +132,45 @@ public final class Integer extends Number implements Comparable<Integer>
}
/**
+ * Return the size of a string large enough to hold the given number
+ *
+ * @param num the number we want the string length for (must be positive)
+ * @param radix the radix (base) that will be used for the string
+ * @return a size sufficient for a string of num
+ */
+ private static int stringSize(int num, int radix) {
+ int exp;
+ if (radix < 4)
+ {
+ exp = 1;
+ }
+ else if (radix < 8)
+ {
+ exp = 2;
+ }
+ else if (radix < 16)
+ {
+ exp = 3;
+ }
+ else if (radix < 32)
+ {
+ exp = 4;
+ }
+ else
+ {
+ exp = 5;
+ }
+ int size=0;
+ do
+ {
+ num >>>= exp;
+ size++;
+ }
+ while(num != 0);
+ return size;
+ }
+
+ /**
* Converts the <code>int</code> to a <code>String</code> using
* the specified radix (base). If the radix exceeds
* <code>Character.MIN_RADIX</code> or <code>Character.MAX_RADIX</code>, 10
@@ -142,22 +187,40 @@ public final class Integer extends Number implements Comparable<Integer>
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
- // For negative numbers, print out the absolute value w/ a leading '-'.
- // Use an array large enough for a binary number.
- char[] buffer = new char[33];
- int i = 33;
- boolean isNeg = false;
- if (num < 0)
+ // Is the value negative?
+ boolean isNeg = num < 0;
+
+ // Is the string a single character?
+ if (!isNeg && num < radix)
+ return new String(digits, num, 1, true);
+
+ // Compute string size and allocate buffer
+ // account for a leading '-' if the value is negative
+ int size;
+ int i;
+ char[] buffer;
+ if (isNeg)
{
- isNeg = true;
num = -num;
// When the value is MIN_VALUE, it overflows when made positive
if (num < 0)
{
+ i = size = stringSize(MAX_VALUE, radix) + 2;
+ buffer = new char[size];
buffer[--i] = digits[(int) (-(num + radix) % radix)];
num = -(num / radix);
}
+ else
+ {
+ i = size = stringSize(num, radix) + 1;
+ buffer = new char[size];
+ }
+ }
+ else
+ {
+ i = size = stringSize(num, radix);
+ buffer = new char[size];
}
do
@@ -171,7 +234,7 @@ public final class Integer extends Number implements Comparable<Integer>
buffer[--i] = '-';
// Package constructor avoids an array copy.
- return new String(buffer, i, 33 - i, true);
+ return new String(buffer, i, size - i, true);
}
/**
@@ -275,7 +338,7 @@ public final class Integer extends Number implements Comparable<Integer>
*/
public static Integer valueOf(String s, int radix)
{
- return new Integer(parseInt(s, radix, false));
+ return valueOf(parseInt(s, radix, false));
}
/**
@@ -291,7 +354,7 @@ public final class Integer extends Number implements Comparable<Integer>
*/
public static Integer valueOf(String s)
{
- return new Integer(parseInt(s, 10, false));
+ return valueOf(parseInt(s, 10, false));
}
/**
@@ -306,12 +369,8 @@ public final class Integer extends Number implements Comparable<Integer>
{
if (val < MIN_CACHE || val > MAX_CACHE)
return new Integer(val);
- synchronized (intCache)
- {
- if (intCache[val - MIN_CACHE] == null)
- intCache[val - MIN_CACHE] = new Integer(val);
- return intCache[val - MIN_CACHE];
- }
+ else
+ return intCache[val - MIN_CACHE];
}
/**
@@ -440,7 +499,7 @@ public final class Integer extends Number implements Comparable<Integer>
public static Integer getInteger(String nm, int val)
{
Integer result = getInteger(nm, null);
- return result == null ? new Integer(val) : result;
+ return result == null ? valueOf(val) : result;
}
/**
@@ -506,7 +565,7 @@ public final class Integer extends Number implements Comparable<Integer>
*/
public static Integer decode(String str)
{
- return new Integer(parseInt(str, 10, true));
+ return valueOf(parseInt(str, 10, true));
}
/**
@@ -628,7 +687,14 @@ public final class Integer extends Number implements Comparable<Integer>
*/
public static int signum(int x)
{
- return x < 0 ? -1 : (x > 0 ? 1 : 0);
+ return (x >> 31) | (-x >>> 31);
+
+ // The LHS propagates the sign bit through every bit in the word;
+ // if X < 0, every bit is set to 1, else 0. if X > 0, the RHS
+ // negates x and shifts the resulting 1 in the sign bit to the
+ // LSB, leaving every other bit 0.
+
+ // Hacker's Delight, Section 2-7
}
/**
@@ -666,10 +732,22 @@ public final class Integer extends Number implements Comparable<Integer>
// Package visible for use by Long.
static String toUnsignedString(int num, int exp)
{
- // Use an array large enough for a binary number.
+ // Compute string length
+ int size = 1;
+ int copy = num >>> exp;
+ while (copy != 0)
+ {
+ size++;
+ copy >>>= exp;
+ }
+ // Quick path for single character strings
+ if (size == 1)
+ return new String(digits, num, 1, true);
+
+ // Encode into buffer
int mask = (1 << exp) - 1;
- char[] buffer = new char[32];
- int i = 32;
+ char[] buffer = new char[size];
+ int i = size;
do
{
buffer[--i] = digits[num & mask];
@@ -678,7 +756,7 @@ public final class Integer extends Number implements Comparable<Integer>
while (num != 0);
// Package constructor avoids an array copy.
- return new String(buffer, i, 32 - i, true);
+ return new String(buffer, i, size - i, true);
}
/**
diff --git a/libjava/classpath/java/lang/Long.java b/libjava/classpath/java/lang/Long.java
index 08ac3976ca7..a5ee6c707ad 100644
--- a/libjava/classpath/java/lang/Long.java
+++ b/libjava/classpath/java/lang/Long.java
@@ -51,6 +51,7 @@ package java.lang;
* @author Eric Blake (ebb9@email.byu.edu)
* @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @author Ian Rogers
* @since 1.0
* @status updated to 1.5
*/
@@ -86,6 +87,18 @@ public final class Long extends Number implements Comparable<Long>
*/
public static final int SIZE = 64;
+ // This caches some Long values, and is used by boxing
+ // conversions via valueOf(). We cache at least -128..127;
+ // these constants control how much we actually cache.
+ private static final int MIN_CACHE = -128;
+ private static final int MAX_CACHE = 127;
+ private static final Long[] longCache = new Long[MAX_CACHE - MIN_CACHE + 1];
+ static
+ {
+ for (int i=MIN_CACHE; i <= MAX_CACHE; i++)
+ longCache[i - MIN_CACHE] = new Long(i);
+ }
+
/**
* The immutable value of this Long.
*
@@ -118,6 +131,45 @@ public final class Long extends Number implements Comparable<Long>
}
/**
+ * Return the size of a string large enough to hold the given number
+ *
+ * @param num the number we want the string length for (must be positive)
+ * @param radix the radix (base) that will be used for the string
+ * @return a size sufficient for a string of num
+ */
+ private static int stringSize(long num, int radix) {
+ int exp;
+ if (radix < 4)
+ {
+ exp = 1;
+ }
+ else if (radix < 8)
+ {
+ exp = 2;
+ }
+ else if (radix < 16)
+ {
+ exp = 3;
+ }
+ else if (radix < 32)
+ {
+ exp = 4;
+ }
+ else
+ {
+ exp = 5;
+ }
+ int size=0;
+ do
+ {
+ num >>>= exp;
+ size++;
+ }
+ while(num != 0);
+ return size;
+ }
+
+ /**
* Converts the <code>long</code> to a <code>String</code> using
* the specified radix (base). If the radix exceeds
* <code>Character.MIN_RADIX</code> or <code>Character.MAX_RADIX</code>, 10
@@ -131,29 +183,43 @@ public final class Long extends Number implements Comparable<Long>
*/
public static String toString(long num, int radix)
{
- // Use the Integer toString for efficiency if possible.
- if ((int) num == num)
- return Integer.toString((int) num, radix);
-
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
- // For negative numbers, print out the absolute value w/ a leading '-'.
- // Use an array large enough for a binary number.
- char[] buffer = new char[65];
- int i = 65;
- boolean isNeg = false;
- if (num < 0)
+ // Is the value negative?
+ boolean isNeg = num < 0;
+
+ // Is the string a single character?
+ if (!isNeg && num < radix)
+ return new String(digits, (int)num, 1, true);
+
+ // Compute string size and allocate buffer
+ // account for a leading '-' if the value is negative
+ int size;
+ int i;
+ char[] buffer;
+ if (isNeg)
{
- isNeg = true;
num = -num;
// When the value is MIN_VALUE, it overflows when made positive
if (num < 0)
- {
- buffer[--i] = digits[(int) (-(num + radix) % radix)];
- num = -(num / radix);
- }
+ {
+ i = size = stringSize(MAX_VALUE, radix) + 2;
+ buffer = new char[size];
+ buffer[--i] = digits[(int) (-(num + radix) % radix)];
+ num = -(num / radix);
+ }
+ else
+ {
+ i = size = stringSize(num, radix) + 1;
+ buffer = new char[size];
+ }
+ }
+ else
+ {
+ i = size = stringSize(num, radix);
+ buffer = new char[size];
}
do
@@ -167,7 +233,7 @@ public final class Long extends Number implements Comparable<Long>
buffer[--i] = '-';
// Package constructor avoids an array copy.
- return new String(buffer, i, 65 - i, true);
+ return new String(buffer, i, size - i, true);
}
/**
@@ -270,7 +336,7 @@ public final class Long extends Number implements Comparable<Long>
*/
public static Long valueOf(String s, int radix)
{
- return new Long(parseLong(s, radix, false));
+ return valueOf(parseLong(s, radix, false));
}
/**
@@ -286,7 +352,7 @@ public final class Long extends Number implements Comparable<Long>
*/
public static Long valueOf(String s)
{
- return new Long(parseLong(s, 10, false));
+ return valueOf(parseLong(s, 10, false));
}
/**
@@ -298,9 +364,10 @@ public final class Long extends Number implements Comparable<Long>
*/
public static Long valueOf(long val)
{
- // We aren't required to cache here. We could, though perhaps we
- // ought to consider that as an empirical question.
- return new Long(val);
+ if (val < MIN_CACHE || val > MAX_CACHE)
+ return new Long(val);
+ else
+ return longCache[((int)val) - MIN_CACHE];
}
/**
@@ -337,7 +404,7 @@ public final class Long extends Number implements Comparable<Long>
*/
public static Long decode(String str)
{
- return new Long(parseLong(str, 10, true));
+ return valueOf(parseLong(str, 10, true));
}
/**
@@ -467,7 +534,7 @@ public final class Long extends Number implements Comparable<Long>
public static Long getLong(String nm, long val)
{
Long result = getLong(nm, null);
- return result == null ? new Long(val) : result;
+ return result == null ? valueOf(val) : result;
}
/**
@@ -622,7 +689,14 @@ public final class Long extends Number implements Comparable<Long>
*/
public static int signum(long x)
{
- return x < 0 ? -1 : (x > 0 ? 1 : 0);
+ return (int) ((x >> 63) | (-x >>> 63));
+
+ // The LHS propagates the sign bit through every bit in the word;
+ // if X < 0, every bit is set to 1, else 0. if X > 0, the RHS
+ // negates x and shifts the resulting 1 in the sign bit to the
+ // LSB, leaving every other bit 0.
+
+ // Hacker's Delight, Section 2-7
}
/**
@@ -655,16 +729,22 @@ public final class Long extends Number implements Comparable<Long>
*/
private static String toUnsignedString(long num, int exp)
{
- // Use the Integer toUnsignedString for efficiency if possible.
- // If NUM<0 then this particular optimization doesn't work
- // properly.
- if (num >= 0 && (int) num == num)
- return Integer.toUnsignedString((int) num, exp);
+ // Compute string length
+ int size = 1;
+ long copy = num >>> exp;
+ while (copy != 0)
+ {
+ size++;
+ copy >>>= exp;
+ }
+ // Quick path for single character strings
+ if (size == 1)
+ return new String(digits, (int)num, 1, true);
- // Use an array large enough for a binary number.
+ // Encode into buffer
int mask = (1 << exp) - 1;
- char[] buffer = new char[64];
- int i = 64;
+ char[] buffer = new char[size];
+ int i = size;
do
{
buffer[--i] = digits[(int) num & mask];
@@ -673,7 +753,7 @@ public final class Long extends Number implements Comparable<Long>
while (num != 0);
// Package constructor avoids an array copy.
- return new String(buffer, i, 64 - i, true);
+ return new String(buffer, i, size - i, true);
}
/**
diff --git a/libjava/classpath/java/lang/Short.java b/libjava/classpath/java/lang/Short.java
index 41a31e26082..ec87f933e93 100644
--- a/libjava/classpath/java/lang/Short.java
+++ b/libjava/classpath/java/lang/Short.java
@@ -90,6 +90,11 @@ public final class Short extends Number implements Comparable<Short>
private static final int MIN_CACHE = -128;
private static final int MAX_CACHE = 127;
private static Short[] shortCache = new Short[MAX_CACHE - MIN_CACHE + 1];
+ static
+ {
+ for (short i=MIN_CACHE; i <= MAX_CACHE; i++)
+ shortCache[i - MIN_CACHE] = new Short(i);
+ }
/**
* The immutable value of this Short.
@@ -184,7 +189,7 @@ public final class Short extends Number implements Comparable<Short>
*/
public static Short valueOf(String s, int radix)
{
- return new Short(parseShort(s, radix));
+ return valueOf(parseShort(s, radix));
}
/**
@@ -200,7 +205,7 @@ public final class Short extends Number implements Comparable<Short>
*/
public static Short valueOf(String s)
{
- return new Short(parseShort(s, 10));
+ return valueOf(parseShort(s, 10));
}
/**
@@ -216,12 +221,8 @@ public final class Short extends Number implements Comparable<Short>
{
if (val < MIN_CACHE || val > MAX_CACHE)
return new Short(val);
- synchronized (shortCache)
- {
- if (shortCache[val - MIN_CACHE] == null)
- shortCache[val - MIN_CACHE] = new Short(val);
- return shortCache[val - MIN_CACHE];
- }
+ else
+ return shortCache[val - MIN_CACHE];
}
/**
@@ -260,7 +261,7 @@ public final class Short extends Number implements Comparable<Short>
int i = Integer.parseInt(s, 10, true);
if ((short) i != i)
throw new NumberFormatException();
- return new Short((short) i);
+ return valueOf((short) i);
}
/**
diff --git a/libjava/classpath/java/lang/String.java b/libjava/classpath/java/lang/String.java
index 0b56accf708..95c88399d3c 100644
--- a/libjava/classpath/java/lang/String.java
+++ b/libjava/classpath/java/lang/String.java
@@ -40,6 +40,7 @@ exception statement from your version. */
package java.lang;
import gnu.java.lang.CharData;
+import gnu.java.lang.CPStringBuilder;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
@@ -2072,7 +2073,7 @@ public final class String
int replaceLength = replacement.length();
int startPos = this.indexOf(targetString);
- StringBuilder result = new StringBuilder(this);
+ CPStringBuilder result = new CPStringBuilder(this);
while (startPos != -1)
{
// Replace the target with the replacement
diff --git a/libjava/classpath/java/lang/StringBuffer.java b/libjava/classpath/java/lang/StringBuffer.java
index 3aa84a21e12..b105f55da56 100644
--- a/libjava/classpath/java/lang/StringBuffer.java
+++ b/libjava/classpath/java/lang/StringBuffer.java
@@ -1,5 +1,5 @@
/* StringBuffer.java -- Growable strings
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -73,6 +73,7 @@ import java.io.Serializable;
* @status updated to 1.4
*/
public final class StringBuffer
+ extends AbstractStringBuffer
implements Serializable, CharSequence, Appendable
{
// Implementation note: if you change this class, you usually will
@@ -84,23 +85,6 @@ public final class StringBuffer
private static final long serialVersionUID = 3388685877147921107L;
/**
- * Index of next available character (and thus the size of the current
- * string contents). Note that this has permissions set this way so that
- * String can get the value.
- *
- * @serial the number of characters in the buffer
- */
- int count;
-
- /**
- * The buffer. Note that this has permissions set this way so that String
- * can get the value.
- *
- * @serial the buffer
- */
- char[] value;
-
- /**
* True if the buffer is shared with another object (StringBuffer or
* String); this means the buffer must be copied before writing to it again.
* Note that this has permissions set this way so that String can get the
@@ -111,16 +95,11 @@ public final class StringBuffer
boolean shared;
/**
- * The default capacity of a buffer.
- */
- private static final int DEFAULT_CAPACITY = 16;
-
- /**
* Create a new StringBuffer with default capacity 16.
*/
public StringBuffer()
{
- this(DEFAULT_CAPACITY);
+ super();
}
/**
@@ -132,7 +111,7 @@ public final class StringBuffer
*/
public StringBuffer(int capacity)
{
- value = new char[capacity];
+ super(capacity);
}
/**
@@ -146,9 +125,7 @@ public final class StringBuffer
public StringBuffer(String str)
{
// Unfortunately, because the size is 16 larger, we cannot share.
- count = str.count;
- value = new char[count + DEFAULT_CAPACITY];
- str.getChars(0, count, value, 0);
+ super(str);
}
/**
@@ -163,11 +140,7 @@ public final class StringBuffer
*/
public StringBuffer(CharSequence seq)
{
- int len = seq.length();
- count = len <= 0 ? 0 : len;
- value = new char[count + DEFAULT_CAPACITY];
- for (int i = 0; i < len; ++i)
- value[i] = seq.charAt(i);
+ super(seq);
}
/**
@@ -226,29 +199,7 @@ public final class StringBuffer
*/
public synchronized void setLength(int newLength)
{
- if (newLength < 0)
- throw new StringIndexOutOfBoundsException(newLength);
-
- int valueLength = value.length;
-
- /* Always call ensureCapacity_unsynchronized in order to preserve
- copy-on-write semantics. */
- ensureCapacity_unsynchronized(newLength);
-
- if (newLength < valueLength)
- {
- /* If the StringBuffer's value just grew, then we know that
- value is newly allocated and the region between count and
- newLength is filled with '\0'. */
- count = newLength;
- }
- else
- {
- /* The StringBuffer's value doesn't need to grow. However,
- we should clear out any cruft that may exist. */
- while (count < newLength)
- value[count++] = '\0';
- }
+ super.setLength(newLength);
}
/**
@@ -257,12 +208,11 @@ public final class StringBuffer
* @param index the index of the character to get, starting at 0
* @return the character at the specified index
* @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
*/
public synchronized char charAt(int index)
{
- if (index < 0 || index >= count)
- throw new StringIndexOutOfBoundsException(index);
- return value[index];
+ return super.charAt(index);
}
/**
@@ -277,7 +227,7 @@ public final class StringBuffer
*/
public synchronized int codePointAt(int index)
{
- return Character.codePointAt(value, index, count);
+ return super.codePointAt(index);
}
/**
@@ -291,11 +241,7 @@ public final class StringBuffer
*/
public synchronized int codePointBefore(int index)
{
- // Character.codePointBefore() doesn't perform this check. We
- // could use the CharSequence overload, but this is just as easy.
- if (index >= count)
- throw new IndexOutOfBoundsException();
- return Character.codePointBefore(value, index, 1);
+ return super.codePointBefore(index);
}
/**
@@ -316,9 +262,7 @@ public final class StringBuffer
public synchronized void getChars(int srcOffset, int srcEnd,
char[] dst, int dstOffset)
{
- if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
- throw new StringIndexOutOfBoundsException();
- VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+ super.getChars(srcOffset, srcEnd, dst, dstOffset);
}
/**
@@ -331,11 +275,7 @@ public final class StringBuffer
*/
public synchronized void setCharAt(int index, char ch)
{
- if (index < 0 || index >= count)
- throw new StringIndexOutOfBoundsException(index);
- // Call ensureCapacity to enforce copy-on-write.
- ensureCapacity_unsynchronized(count);
- value[index] = ch;
+ super.setCharAt(index, ch);
}
/**
@@ -348,9 +288,10 @@ public final class StringBuffer
* @see String#valueOf(Object)
* @see #append(String)
*/
- public StringBuffer append(Object obj)
+ public synchronized StringBuffer append(Object obj)
{
- return append(obj == null ? "null" : obj.toString());
+ super.append(obj);
+ return this;
}
/**
@@ -362,12 +303,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer append(String str)
{
- if (str == null)
- str = "null";
- int len = str.count;
- ensureCapacity_unsynchronized(count + len);
- str.getChars(0, len, value, count);
- count += len;
+ super.append(str);
return this;
}
@@ -383,15 +319,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer append(StringBuffer stringBuffer)
{
- if (stringBuffer == null)
- return append("null");
- synchronized (stringBuffer)
- {
- int len = stringBuffer.count;
- ensureCapacity_unsynchronized(count + len);
- VMSystem.arraycopy(stringBuffer.value, 0, value, count, len);
- count += len;
- }
+ super.append(stringBuffer);
return this;
}
@@ -405,9 +333,10 @@ public final class StringBuffer
* @throws NullPointerException if <code>str</code> is <code>null</code>
* @see #append(char[], int, int)
*/
- public StringBuffer append(char[] data)
+ public synchronized StringBuffer append(char[] data)
{
- return append(data, 0, data.length);
+ super.append(data, 0, data.length);
+ return this;
}
/**
@@ -426,30 +355,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer append(char[] data, int offset, int count)
{
- if (offset < 0 || count < 0 || offset > data.length - count)
- throw new StringIndexOutOfBoundsException();
- ensureCapacity_unsynchronized(this.count + count);
- VMSystem.arraycopy(data, offset, value, this.count, count);
- this.count += count;
- return this;
- }
-
- /**
- * Append the code point to this <code>StringBuffer</code>.
- * This is like #append(char), but will append two characters
- * if a supplementary code point is given.
- *
- * @param code the code point to append
- * @return this <code>StringBuffer</code>
- * @see Character#toChars(int, char[], int)
- * @since 1.5
- */
- public synchronized StringBuffer appendCodePoint(int code)
- {
- int len = Character.charCount(code);
- ensureCapacity_unsynchronized(count + len);
- Character.toChars(code, value, count);
- count += len;
+ super.append(data, offset, count);
return this;
}
@@ -462,9 +368,10 @@ public final class StringBuffer
* @return this <code>StringBuffer</code>
* @see String#valueOf(boolean)
*/
- public StringBuffer append(boolean bool)
+ public synchronized StringBuffer append(boolean bool)
{
- return append(bool ? "true" : "false");
+ super.append(bool);
+ return this;
}
/**
@@ -475,8 +382,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer append(char ch)
{
- ensureCapacity_unsynchronized(count + 1);
- value[count++] = ch;
+ super.append(ch);
return this;
}
@@ -490,7 +396,8 @@ public final class StringBuffer
*/
public synchronized StringBuffer append(CharSequence seq)
{
- return append(seq, 0, seq.length());
+ super.append(seq, 0, seq.length());
+ return this;
}
/**
@@ -506,14 +413,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer append(CharSequence seq, int start, int end)
{
- if (seq == null)
- return append("null");
- if (end - start > 0)
- {
- ensureCapacity_unsynchronized(count + end - start);
- for (; start < end; ++start)
- value[count++] = seq.charAt(start);
- }
+ super.append(seq, start, end);
return this;
}
@@ -527,9 +427,10 @@ public final class StringBuffer
* @see String#valueOf(int)
*/
// This is native in libgcj, for efficiency.
- public StringBuffer append(int inum)
+ public synchronized StringBuffer append(int inum)
{
- return append(String.valueOf(inum));
+ super.append(inum);
+ return this;
}
/**
@@ -541,9 +442,10 @@ public final class StringBuffer
* @return this <code>StringBuffer</code>
* @see String#valueOf(long)
*/
- public StringBuffer append(long lnum)
+ public synchronized StringBuffer append(long lnum)
{
- return append(Long.toString(lnum, 10));
+ super.append(lnum);
+ return this;
}
/**
@@ -555,9 +457,10 @@ public final class StringBuffer
* @return this <code>StringBuffer</code>
* @see String#valueOf(float)
*/
- public StringBuffer append(float fnum)
+ public synchronized StringBuffer append(float fnum)
{
- return append(Float.toString(fnum));
+ super.append(fnum);
+ return this;
}
/**
@@ -569,9 +472,26 @@ public final class StringBuffer
* @return this <code>StringBuffer</code>
* @see String#valueOf(double)
*/
- public StringBuffer append(double dnum)
+ public synchronized StringBuffer append(double dnum)
{
- return append(Double.toString(dnum));
+ super.append(dnum);
+ return this;
+ }
+
+ /**
+ * Append the code point to this <code>StringBuffer</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuffer</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public synchronized StringBuffer appendCodePoint(int code)
+ {
+ super.appendCodePoint(code);
+ return this;
}
/**
@@ -587,15 +507,8 @@ public final class StringBuffer
*/
public synchronized StringBuffer delete(int start, int end)
{
- if (start < 0 || start > count || start > end)
- throw new StringIndexOutOfBoundsException(start);
- if (end > count)
- end = count;
// This will unshare if required.
- ensureCapacity_unsynchronized(count);
- if (count - end != 0)
- VMSystem.arraycopy(value, end, value, start, count - end);
- count -= end - start;
+ super.delete(start, end);
return this;
}
@@ -607,9 +520,10 @@ public final class StringBuffer
* @throws StringIndexOutOfBoundsException if index is out of bounds
* @since 1.2
*/
- public StringBuffer deleteCharAt(int index)
+ public synchronized StringBuffer deleteCharAt(int index)
{
- return delete(index, index + 1);
+ super.deleteCharAt(index);
+ return this;
}
/**
@@ -628,19 +542,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer replace(int start, int end, String str)
{
- if (start < 0 || start > count || start > end)
- throw new StringIndexOutOfBoundsException(start);
-
- int len = str.count;
- // Calculate the difference in 'count' after the replace.
- int delta = len - (end > count ? count : end) + start;
- ensureCapacity_unsynchronized(count + delta);
-
- if (delta != 0 && end < count)
- VMSystem.arraycopy(value, end, value, end + delta, count - end);
-
- str.getChars(0, len, value, start);
- count += delta;
+ super.replace(start, end, str);
return this;
}
@@ -720,13 +622,7 @@ public final class StringBuffer
public synchronized StringBuffer insert(int offset,
char[] str, int str_offset, int len)
{
- if (offset < 0 || offset > count || len < 0
- || str_offset < 0 || str_offset > str.length - len)
- throw new StringIndexOutOfBoundsException();
- ensureCapacity_unsynchronized(count + len);
- VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
- VMSystem.arraycopy(str, str_offset, value, offset, len);
- count += len;
+ super.insert(offset, str, str_offset, len);
return this;
}
@@ -741,9 +637,10 @@ public final class StringBuffer
* @exception StringIndexOutOfBoundsException if offset is out of bounds
* @see String#valueOf(Object)
*/
- public StringBuffer insert(int offset, Object obj)
+ public synchronized StringBuffer insert(int offset, Object obj)
{
- return insert(offset, obj == null ? "null" : obj.toString());
+ super.insert(offset, obj);
+ return this;
}
/**
@@ -758,15 +655,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer insert(int offset, String str)
{
- if (offset < 0 || offset > count)
- throw new StringIndexOutOfBoundsException(offset);
- if (str == null)
- str = "null";
- int len = str.count;
- ensureCapacity_unsynchronized(count + len);
- VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
- str.getChars(0, len, value, offset);
- count += len;
+ super.insert(offset, str);
return this;
}
@@ -783,9 +672,8 @@ public final class StringBuffer
*/
public synchronized StringBuffer insert(int offset, CharSequence sequence)
{
- if (sequence == null)
- sequence = "null";
- return insert(offset, sequence, 0, sequence.length());
+ super.insert(offset, sequence);
+ return this;
}
/**
@@ -805,16 +693,7 @@ public final class StringBuffer
public synchronized StringBuffer insert(int offset, CharSequence sequence,
int start, int end)
{
- if (sequence == null)
- sequence = "null";
- if (start < 0 || end < 0 || start > end || end > sequence.length())
- throw new IndexOutOfBoundsException();
- int len = end - start;
- ensureCapacity_unsynchronized(count + len);
- VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
- for (int i = start; i < end; ++i)
- value[offset++] = sequence.charAt(i);
- count += len;
+ super.insert(offset, sequence, start, end);
return this;
}
@@ -829,9 +708,10 @@ public final class StringBuffer
* @throws StringIndexOutOfBoundsException if offset is out of bounds
* @see #insert(int, char[], int, int)
*/
- public StringBuffer insert(int offset, char[] data)
+ public synchronized StringBuffer insert(int offset, char[] data)
{
- return insert(offset, data, 0, data.length);
+ super.insert(offset, data, 0, data.length);
+ return this;
}
/**
@@ -845,9 +725,10 @@ public final class StringBuffer
* @throws StringIndexOutOfBoundsException if offset is out of bounds
* @see String#valueOf(boolean)
*/
- public StringBuffer insert(int offset, boolean bool)
+ public synchronized StringBuffer insert(int offset, boolean bool)
{
- return insert(offset, bool ? "true" : "false");
+ super.insert(offset, bool);
+ return this;
}
/**
@@ -860,12 +741,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer insert(int offset, char ch)
{
- if (offset < 0 || offset > count)
- throw new StringIndexOutOfBoundsException(offset);
- ensureCapacity_unsynchronized(count + 1);
- VMSystem.arraycopy(value, offset, value, offset + 1, count - offset);
- value[offset] = ch;
- count++;
+ super.insert(offset, ch);
return this;
}
@@ -880,9 +756,10 @@ public final class StringBuffer
* @throws StringIndexOutOfBoundsException if offset is out of bounds
* @see String#valueOf(int)
*/
- public StringBuffer insert(int offset, int inum)
+ public synchronized StringBuffer insert(int offset, int inum)
{
- return insert(offset, String.valueOf(inum));
+ super.insert(offset, inum);
+ return this;
}
/**
@@ -896,9 +773,10 @@ public final class StringBuffer
* @throws StringIndexOutOfBoundsException if offset is out of bounds
* @see String#valueOf(long)
*/
- public StringBuffer insert(int offset, long lnum)
+ public synchronized StringBuffer insert(int offset, long lnum)
{
- return insert(offset, Long.toString(lnum, 10));
+ super.insert(offset, lnum);
+ return this;
}
/**
@@ -912,9 +790,10 @@ public final class StringBuffer
* @throws StringIndexOutOfBoundsException if offset is out of bounds
* @see String#valueOf(float)
*/
- public StringBuffer insert(int offset, float fnum)
+ public synchronized StringBuffer insert(int offset, float fnum)
{
- return insert(offset, Float.toString(fnum));
+ super.insert(offset, fnum);
+ return this;
}
/**
@@ -928,9 +807,10 @@ public final class StringBuffer
* @throws StringIndexOutOfBoundsException if offset is out of bounds
* @see String#valueOf(double)
*/
- public StringBuffer insert(int offset, double dnum)
+ public synchronized StringBuffer insert(int offset, double dnum)
{
- return insert(offset, Double.toString(dnum));
+ super.insert(offset, dnum);
+ return this;
}
/**
@@ -942,9 +822,9 @@ public final class StringBuffer
* @see #indexOf(String, int)
* @since 1.4
*/
- public int indexOf(String str)
+ public synchronized int indexOf(String str)
{
- return indexOf(str, 0);
+ return super.indexOf(str, 0);
}
/**
@@ -961,13 +841,7 @@ public final class StringBuffer
*/
public synchronized int indexOf(String str, int fromIndex)
{
- if (fromIndex < 0)
- fromIndex = 0;
- int limit = count - str.count;
- for ( ; fromIndex <= limit; fromIndex++)
- if (regionMatches(fromIndex, str))
- return fromIndex;
- return -1;
+ return super.indexOf(str, fromIndex);
}
/**
@@ -979,9 +853,9 @@ public final class StringBuffer
* @see #lastIndexOf(String, int)
* @since 1.4
*/
- public int lastIndexOf(String str)
+ public synchronized int lastIndexOf(String str)
{
- return lastIndexOf(str, count - str.count);
+ return super.lastIndexOf(str, count - str.count);
}
/**
@@ -998,11 +872,7 @@ public final class StringBuffer
*/
public synchronized int lastIndexOf(String str, int fromIndex)
{
- fromIndex = Math.min(fromIndex, count - str.count);
- for ( ; fromIndex >= 0; fromIndex--)
- if (regionMatches(fromIndex, str))
- return fromIndex;
- return -1;
+ return super.lastIndexOf(str, fromIndex);
}
/**
@@ -1013,14 +883,7 @@ public final class StringBuffer
*/
public synchronized StringBuffer reverse()
{
- // Call ensureCapacity to enforce copy-on-write.
- ensureCapacity_unsynchronized(count);
- for (int i = count >> 1, j = count - i; --i >= 0; ++j)
- {
- char c = value[i];
- value[i] = value[j];
- value[j] = c;
- }
+ super.reverse();
return this;
}
@@ -1047,19 +910,7 @@ public final class StringBuffer
*/
public synchronized void trimToSize()
{
- int wouldSave = value.length - count;
- // Some random heuristics: if we save less than 20 characters, who
- // cares.
- if (wouldSave < 20)
- return;
- // If we save more than 200 characters, shrink.
- // If we save more than 1/4 of the buffer, shrink.
- if (wouldSave > 200 || wouldSave * 4 > value.length)
- {
- char[] newValue = new char[count];
- VMSystem.arraycopy(value, 0, newValue, 0, count);
- value = newValue;
- }
+ super.trimToSize();
}
/**
@@ -1076,31 +927,7 @@ public final class StringBuffer
*/
public synchronized int codePointCount(int start, int end)
{
- if (start < 0 || end >= count || start > end)
- throw new StringIndexOutOfBoundsException();
-
- int count = 0;
- while (start < end)
- {
- char base = value[start];
- if (base < Character.MIN_HIGH_SURROGATE
- || base > Character.MAX_HIGH_SURROGATE
- || start == end
- || start == count
- || value[start + 1] < Character.MIN_LOW_SURROGATE
- || value[start + 1] > Character.MAX_LOW_SURROGATE)
- {
- // Nothing.
- }
- else
- {
- // Surrogate pair.
- ++start;
- }
- ++start;
- ++count;
- }
- return count;
+ return super.codePointCount(start, end);
}
/**
@@ -1116,26 +943,7 @@ public final class StringBuffer
*/
public synchronized int offsetByCodePoints(int start, int codePoints)
{
- while (codePoints > 0)
- {
- char base = value[start];
- if (base < Character.MIN_HIGH_SURROGATE
- || base > Character.MAX_HIGH_SURROGATE
- || start == count
- || value[start + 1] < Character.MIN_LOW_SURROGATE
- || value[start + 1] > Character.MAX_LOW_SURROGATE)
- {
- // Nothing.
- }
- else
- {
- // Surrogate pair.
- ++start;
- }
- ++start;
- --codePoints;
- }
- return start;
+ return super.offsetByCodePoints(start, codePoints);
}
/**
@@ -1147,7 +955,7 @@ public final class StringBuffer
* @param minimumCapacity the minimum capacity
* @see #ensureCapacity(int)
*/
- private void ensureCapacity_unsynchronized(int minimumCapacity)
+ void ensureCapacity_unsynchronized(int minimumCapacity)
{
if (shared || minimumCapacity > value.length)
{
@@ -1165,26 +973,4 @@ public final class StringBuffer
}
}
- /**
- * Predicate which determines if a substring of this matches another String
- * starting at a specified offset for each String and continuing for a
- * specified length. This is more efficient than creating a String to call
- * indexOf on.
- *
- * @param toffset index to start comparison at for this String
- * @param other non-null String to compare to region of this
- * @return true if regions match, false otherwise
- * @see #indexOf(String, int)
- * @see #lastIndexOf(String, int)
- * @see String#regionMatches(boolean, int, String, int, int)
- */
- private boolean regionMatches(int toffset, String other)
- {
- int len = other.count;
- int index = other.offset;
- while (--len >= 0)
- if (value[toffset++] != other.value[index++])
- return false;
- return true;
- }
}
diff --git a/libjava/classpath/java/lang/StringBuilder.java b/libjava/classpath/java/lang/StringBuilder.java
index 95d04d1e766..aefe9272b6e 100644
--- a/libjava/classpath/java/lang/StringBuilder.java
+++ b/libjava/classpath/java/lang/StringBuilder.java
@@ -1,5 +1,5 @@
/* StringBuilder.java -- Unsynchronized growable strings
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -75,6 +75,7 @@ import java.io.Serializable;
* @since 1.5
*/
public final class StringBuilder
+ extends AbstractStringBuffer
implements Serializable, CharSequence, Appendable
{
// Implementation note: if you change this class, you usually will
@@ -86,33 +87,11 @@ public final class StringBuilder
private static final long serialVersionUID = 4383685877147921099L;
/**
- * Index of next available character (and thus the size of the current
- * string contents). Note that this has permissions set this way so that
- * String can get the value.
- *
- * @serial the number of characters in the buffer
- */
- int count;
-
- /**
- * The buffer. Note that this has permissions set this way so that String
- * can get the value.
- *
- * @serial the buffer
- */
- char[] value;
-
- /**
- * The default capacity of a buffer.
- */
- private static final int DEFAULT_CAPACITY = 16;
-
- /**
* Create a new StringBuilder with default capacity 16.
*/
public StringBuilder()
{
- this(DEFAULT_CAPACITY);
+ super();
}
/**
@@ -124,7 +103,7 @@ public final class StringBuilder
*/
public StringBuilder(int capacity)
{
- value = new char[capacity];
+ super(capacity);
}
/**
@@ -137,10 +116,7 @@ public final class StringBuilder
*/
public StringBuilder(String str)
{
- // Unfortunately, because the size is 16 larger, we cannot share.
- count = str.count;
- value = new char[count + DEFAULT_CAPACITY];
- str.getChars(0, count, value, 0);
+ super(str);
}
/**
@@ -154,11 +130,7 @@ public final class StringBuilder
*/
public StringBuilder(CharSequence seq)
{
- int len = seq.length();
- count = len <= 0 ? 0 : len;
- value = new char[count + DEFAULT_CAPACITY];
- for (int i = 0; i < len; ++i)
- value[i] = seq.charAt(i);
+ super(seq);
}
/**
@@ -189,122 +161,6 @@ public final class StringBuilder
}
/**
- * Increase the capacity of this <code>StringBuilder</code>. This will
- * ensure that an expensive growing operation will not occur until
- * <code>minimumCapacity</code> is reached. The buffer is grown to the
- * larger of <code>minimumCapacity</code> and
- * <code>capacity() * 2 + 2</code>, if it is not already large enough.
- *
- * @param minimumCapacity the new capacity
- * @see #capacity()
- */
- public void ensureCapacity(int minimumCapacity)
- {
- if (minimumCapacity > value.length)
- {
- int max = value.length * 2 + 2;
- minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
- char[] nb = new char[minimumCapacity];
- VMSystem.arraycopy(value, 0, nb, 0, count);
- value = nb;
- }
- }
-
- /**
- * Set the length of this StringBuilder. If the new length is greater than
- * the current length, all the new characters are set to '\0'. If the new
- * length is less than the current length, the first <code>newLength</code>
- * characters of the old array will be preserved, and the remaining
- * characters are truncated.
- *
- * @param newLength the new length
- * @throws IndexOutOfBoundsException if the new length is negative
- * (while unspecified, this is a StringIndexOutOfBoundsException)
- * @see #length()
- */
- public void setLength(int newLength)
- {
- if (newLength < 0)
- throw new StringIndexOutOfBoundsException(newLength);
-
- int valueLength = value.length;
-
- /* Always call ensureCapacity in order to preserve copy-on-write
- semantics. */
- ensureCapacity(newLength);
-
- if (newLength < valueLength)
- {
- /* If the StringBuilder's value just grew, then we know that
- value is newly allocated and the region between count and
- newLength is filled with '\0'. */
- count = newLength;
- }
- else
- {
- /* The StringBuilder's value doesn't need to grow. However,
- we should clear out any cruft that may exist. */
- while (count < newLength)
- value[count++] = '\0';
- }
- }
-
- /**
- * Get the character at the specified index.
- *
- * @param index the index of the character to get, starting at 0
- * @return the character at the specified index
- * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
- * (while unspecified, this is a StringIndexOutOfBoundsException)
- */
- public char charAt(int index)
- {
- if (index < 0 || index >= count)
- throw new StringIndexOutOfBoundsException(index);
- return value[index];
- }
-
- /**
- * Get the specified array of characters. <code>srcOffset - srcEnd</code>
- * characters will be copied into the array you pass in.
- *
- * @param srcOffset the index to start copying from (inclusive)
- * @param srcEnd the index to stop copying from (exclusive)
- * @param dst the array to copy into
- * @param dstOffset the index to start copying into
- * @throws NullPointerException if dst is null
- * @throws IndexOutOfBoundsException if any source or target indices are
- * out of range (while unspecified, source problems cause a
- * StringIndexOutOfBoundsException, and dest problems cause an
- * ArrayIndexOutOfBoundsException)
- * @see System#arraycopy(Object, int, Object, int, int)
- */
- public void getChars(int srcOffset, int srcEnd,
- char[] dst, int dstOffset)
- {
- if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
- throw new StringIndexOutOfBoundsException();
- VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
- }
-
- /**
- * Set the character at the specified index.
- *
- * @param index the index of the character to set starting at 0
- * @param ch the value to set that character to
- * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
- * (while unspecified, this is a StringIndexOutOfBoundsException)
- */
- public void setCharAt(int index, char ch)
- {
- if (index < 0 || index >= count)
- throw new StringIndexOutOfBoundsException(index);
- // Call ensureCapacity to enforce copy-on-write.
- ensureCapacity(count);
- value[index] = ch;
- }
-
- /**
* Append the <code>String</code> value of the argument to this
* <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
* to <code>String</code>.
@@ -316,7 +172,8 @@ public final class StringBuilder
*/
public StringBuilder append(Object obj)
{
- return append(obj == null ? "null" : obj.toString());
+ super.append(obj);
+ return this;
}
/**
@@ -328,12 +185,7 @@ public final class StringBuilder
*/
public StringBuilder append(String str)
{
- if (str == null)
- str = "null";
- int len = str.count;
- ensureCapacity(count + len);
- str.getChars(0, len, value, count);
- count += len;
+ super.append(str);
return this;
}
@@ -348,15 +200,7 @@ public final class StringBuilder
*/
public StringBuilder append(StringBuffer stringBuffer)
{
- if (stringBuffer == null)
- return append("null");
- synchronized (stringBuffer)
- {
- int len = stringBuffer.count;
- ensureCapacity(count + len);
- VMSystem.arraycopy(stringBuffer.value, 0, value, count, len);
- count += len;
- }
+ super.append(stringBuffer);
return this;
}
@@ -372,7 +216,8 @@ public final class StringBuilder
*/
public StringBuilder append(char[] data)
{
- return append(data, 0, data.length);
+ super.append(data, 0, data.length);
+ return this;
}
/**
@@ -391,11 +236,7 @@ public final class StringBuilder
*/
public StringBuilder append(char[] data, int offset, int count)
{
- if (offset < 0 || count < 0 || offset > data.length - count)
- throw new StringIndexOutOfBoundsException();
- ensureCapacity(this.count + count);
- VMSystem.arraycopy(data, offset, value, this.count, count);
- this.count += count;
+ super.append(data, offset, count);
return this;
}
@@ -410,7 +251,8 @@ public final class StringBuilder
*/
public StringBuilder append(boolean bool)
{
- return append(bool ? "true" : "false");
+ super.append(bool);
+ return this;
}
/**
@@ -421,8 +263,7 @@ public final class StringBuilder
*/
public StringBuilder append(char ch)
{
- ensureCapacity(count + 1);
- value[count++] = ch;
+ super.append(ch);
return this;
}
@@ -435,7 +276,8 @@ public final class StringBuilder
*/
public StringBuilder append(CharSequence seq)
{
- return append(seq, 0, seq.length());
+ super.append(seq, 0, seq.length());
+ return this;
}
/**
@@ -451,33 +293,7 @@ public final class StringBuilder
public StringBuilder append(CharSequence seq, int start,
int end)
{
- if (seq == null)
- return append("null");
- if (end - start > 0)
- {
- ensureCapacity(count + end - start);
- for (; start < end; ++start)
- value[count++] = seq.charAt(start);
- }
- return this;
- }
-
- /**
- * Append the code point to this <code>StringBuilder</code>.
- * This is like #append(char), but will append two characters
- * if a supplementary code point is given.
- *
- * @param code the code point to append
- * @return this <code>StringBuilder</code>
- * @see Character#toChars(int, char[], int)
- * @since 1.5
- */
- public synchronized StringBuilder appendCodePoint(int code)
- {
- int len = Character.charCount(code);
- ensureCapacity(count + len);
- Character.toChars(code, value, count);
- count += len;
+ super.append(seq, start, end);
return this;
}
@@ -493,7 +309,8 @@ public final class StringBuilder
// This is native in libgcj, for efficiency.
public StringBuilder append(int inum)
{
- return append(String.valueOf(inum));
+ super.append(inum);
+ return this;
}
/**
@@ -507,7 +324,8 @@ public final class StringBuilder
*/
public StringBuilder append(long lnum)
{
- return append(Long.toString(lnum, 10));
+ super.append(lnum);
+ return this;
}
/**
@@ -521,7 +339,8 @@ public final class StringBuilder
*/
public StringBuilder append(float fnum)
{
- return append(Float.toString(fnum));
+ super.append(fnum);
+ return this;
}
/**
@@ -535,7 +354,24 @@ public final class StringBuilder
*/
public StringBuilder append(double dnum)
{
- return append(Double.toString(dnum));
+ super.append(dnum);
+ return this;
+ }
+
+ /**
+ * Append the code point to this <code>StringBuilder</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuilder</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public StringBuilder appendCodePoint(int code)
+ {
+ super.appendCodePoint(code);
+ return this;
}
/**
@@ -550,15 +386,7 @@ public final class StringBuilder
*/
public StringBuilder delete(int start, int end)
{
- if (start < 0 || start > count || start > end)
- throw new StringIndexOutOfBoundsException(start);
- if (end > count)
- end = count;
- // This will unshare if required.
- ensureCapacity(count);
- if (count - end != 0)
- VMSystem.arraycopy(value, end, value, start, count - end);
- count -= end - start;
+ super.delete(start, end);
return this;
}
@@ -571,7 +399,8 @@ public final class StringBuilder
*/
public StringBuilder deleteCharAt(int index)
{
- return delete(index, index + 1);
+ super.deleteCharAt(index);
+ return this;
}
/**
@@ -589,19 +418,7 @@ public final class StringBuilder
*/
public StringBuilder replace(int start, int end, String str)
{
- if (start < 0 || start > count || start > end)
- throw new StringIndexOutOfBoundsException(start);
-
- int len = str.count;
- // Calculate the difference in 'count' after the replace.
- int delta = len - (end > count ? count : end) + start;
- ensureCapacity(count + delta);
-
- if (delta != 0 && end < count)
- VMSystem.arraycopy(value, end, value, end + delta, count - end);
-
- str.getChars(0, len, value, start);
- count += delta;
+ super.replace(start, end, str);
return this;
}
@@ -672,13 +489,7 @@ public final class StringBuilder
public StringBuilder insert(int offset,
char[] str, int str_offset, int len)
{
- if (offset < 0 || offset > count || len < 0
- || str_offset < 0 || str_offset > str.length - len)
- throw new StringIndexOutOfBoundsException();
- ensureCapacity(count + len);
- VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
- VMSystem.arraycopy(str, str_offset, value, offset, len);
- count += len;
+ super.insert(offset, str, str_offset, len);
return this;
}
@@ -695,7 +506,8 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, Object obj)
{
- return insert(offset, obj == null ? "null" : obj.toString());
+ super.insert(offset, obj);
+ return this;
}
/**
@@ -710,15 +522,7 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, String str)
{
- if (offset < 0 || offset > count)
- throw new StringIndexOutOfBoundsException(offset);
- if (str == null)
- str = "null";
- int len = str.count;
- ensureCapacity(count + len);
- VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
- str.getChars(0, len, value, offset);
- count += len;
+ super.insert(offset, str);
return this;
}
@@ -732,11 +536,10 @@ public final class StringBuilder
* @return this <code>StringBuilder</code>
* @throws IndexOutOfBoundsException if offset is out of bounds
*/
- public synchronized StringBuilder insert(int offset, CharSequence sequence)
+ public StringBuilder insert(int offset, CharSequence sequence)
{
- if (sequence == null)
- sequence = "null";
- return insert(offset, sequence, 0, sequence.length());
+ super.insert(offset, sequence);
+ return this;
}
/**
@@ -752,19 +555,10 @@ public final class StringBuilder
* @throws IndexOutOfBoundsException if offset, start,
* or end are out of bounds
*/
- public synchronized StringBuilder insert(int offset, CharSequence sequence,
- int start, int end)
+ public StringBuilder insert(int offset, CharSequence sequence,
+ int start, int end)
{
- if (sequence == null)
- sequence = "null";
- if (start < 0 || end < 0 || start > end || end > sequence.length())
- throw new IndexOutOfBoundsException();
- int len = end - start;
- ensureCapacity(count + len);
- VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
- for (int i = start; i < end; ++i)
- value[offset++] = sequence.charAt(i);
- count += len;
+ super.insert(offset, sequence, start, end);
return this;
}
@@ -781,7 +575,8 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, char[] data)
{
- return insert(offset, data, 0, data.length);
+ super.insert(offset, data);
+ return this;
}
/**
@@ -797,7 +592,8 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, boolean bool)
{
- return insert(offset, bool ? "true" : "false");
+ super.insert(offset, bool);
+ return this;
}
/**
@@ -810,12 +606,7 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, char ch)
{
- if (offset < 0 || offset > count)
- throw new StringIndexOutOfBoundsException(offset);
- ensureCapacity(count + 1);
- VMSystem.arraycopy(value, offset, value, offset + 1, count - offset);
- value[offset] = ch;
- count++;
+ super.insert(offset, ch);
return this;
}
@@ -832,7 +623,8 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, int inum)
{
- return insert(offset, String.valueOf(inum));
+ super.insert(offset, inum);
+ return this;
}
/**
@@ -848,7 +640,8 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, long lnum)
{
- return insert(offset, Long.toString(lnum, 10));
+ super.insert(offset, lnum);
+ return this;
}
/**
@@ -864,7 +657,8 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, float fnum)
{
- return insert(offset, Float.toString(fnum));
+ super.insert(offset, fnum);
+ return this;
}
/**
@@ -880,75 +674,8 @@ public final class StringBuilder
*/
public StringBuilder insert(int offset, double dnum)
{
- return insert(offset, Double.toString(dnum));
- }
-
- /**
- * Finds the first instance of a substring in this StringBuilder.
- *
- * @param str String to find
- * @return location (base 0) of the String, or -1 if not found
- * @throws NullPointerException if str is null
- * @see #indexOf(String, int)
- */
- public int indexOf(String str)
- {
- return indexOf(str, 0);
- }
-
- /**
- * Finds the first instance of a String in this StringBuilder, starting at
- * a given index. If starting index is less than 0, the search starts at
- * the beginning of this String. If the starting index is greater than the
- * length of this String, or the substring is not found, -1 is returned.
- *
- * @param str String to find
- * @param fromIndex index to start the search
- * @return location (base 0) of the String, or -1 if not found
- * @throws NullPointerException if str is null
- */
- public int indexOf(String str, int fromIndex)
- {
- if (fromIndex < 0)
- fromIndex = 0;
- int limit = count - str.count;
- for ( ; fromIndex <= limit; fromIndex++)
- if (regionMatches(fromIndex, str))
- return fromIndex;
- return -1;
- }
-
- /**
- * Finds the last instance of a substring in this StringBuilder.
- *
- * @param str String to find
- * @return location (base 0) of the String, or -1 if not found
- * @throws NullPointerException if str is null
- * @see #lastIndexOf(String, int)
- */
- public int lastIndexOf(String str)
- {
- return lastIndexOf(str, count - str.count);
- }
-
- /**
- * Finds the last instance of a String in this StringBuilder, starting at a
- * given index. If starting index is greater than the maximum valid index,
- * then the search begins at the end of this String. If the starting index
- * is less than zero, or the substring is not found, -1 is returned.
- *
- * @param str String to find
- * @param fromIndex index to start the search
- * @return location (base 0) of the String, or -1 if not found
- * @throws NullPointerException if str is null
- */
- public int lastIndexOf(String str, int fromIndex)
- {
- fromIndex = Math.min(fromIndex, count - str.count);
- for ( ; fromIndex >= 0; fromIndex--)
- if (regionMatches(fromIndex, str))
- return fromIndex;
- return -1;
+ super.insert(offset, dnum);
+ return this;
}
/**
@@ -959,14 +686,7 @@ public final class StringBuilder
*/
public StringBuilder reverse()
{
- // Call ensureCapacity to enforce copy-on-write.
- ensureCapacity(count);
- for (int i = count >> 1, j = count - i; --i >= 0; ++j)
- {
- char c = value[i];
- value[i] = value[j];
- value[j] = c;
- }
+ super.reverse();
return this;
}
@@ -983,87 +703,4 @@ public final class StringBuilder
return new String(this);
}
- /**
- * Predicate which determines if a substring of this matches another String
- * starting at a specified offset for each String and continuing for a
- * specified length. This is more efficient than creating a String to call
- * indexOf on.
- *
- * @param toffset index to start comparison at for this String
- * @param other non-null String to compare to region of this
- * @return true if regions match, false otherwise
- * @see #indexOf(String, int)
- * @see #lastIndexOf(String, int)
- * @see String#regionMatches(boolean, int, String, int, int)
- */
- private boolean regionMatches(int toffset, String other)
- {
- int len = other.count;
- int index = other.offset;
- while (--len >= 0)
- if (value[toffset++] != other.value[index++])
- return false;
- return true;
- }
-
- /**
- * Get the code point at the specified index. This is like #charAt(int),
- * but if the character is the start of a surrogate pair, and the
- * following character completes the pair, then the corresponding
- * supplementary code point is returned.
- * @param index the index of the codepoint to get, starting at 0
- * @return the codepoint at the specified index
- * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
- * @since 1.5
- */
- public int codePointAt(int index)
- {
- return Character.codePointAt(value, index, count);
- }
-
- /**
- * Get the code point before the specified index. This is like
- * #codePointAt(int), but checks the characters at <code>index-1</code> and
- * <code>index-2</code> to see if they form a supplementary code point.
- * @param index the index just past the codepoint to get, starting at 0
- * @return the codepoint at the specified index
- * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
- * @since 1.5
- */
- public int codePointBefore(int index)
- {
- // Character.codePointBefore() doesn't perform this check. We
- // could use the CharSequence overload, but this is just as easy.
- if (index >= count)
- throw new IndexOutOfBoundsException();
- return Character.codePointBefore(value, index, 1);
- }
-
- /**
- * Returns the number of Unicode code points in the specified sub sequence.
- * Surrogate pairs count as one code point.
- * @param beginIndex the start of the subarray
- * @param endIndex the index after the last char in the subarray
- * @return the number of code points
- * @throws IndexOutOfBoundsException if beginIndex is less than zero or
- * greater than endIndex or if endIndex is greater than the length of this
- * StringBuilder
- */
- public int codePointCount(int beginIndex,int endIndex)
- {
- if (beginIndex < 0 || beginIndex > endIndex || endIndex > count)
- throw new IndexOutOfBoundsException("invalid indices: " + beginIndex
- + ", " + endIndex);
- return Character.codePointCount(value, beginIndex, endIndex - beginIndex);
- }
-
- public void trimToSize()
- {
- if (count < value.length)
- {
- char[] newValue = new char[count];
- VMSystem.arraycopy(value, 0, newValue, 0, count);
- value = newValue;
- }
- }
}
diff --git a/libjava/classpath/java/lang/Thread.java b/libjava/classpath/java/lang/Thread.java
index 01b380b67b5..82e72618780 100644
--- a/libjava/classpath/java/lang/Thread.java
+++ b/libjava/classpath/java/lang/Thread.java
@@ -159,7 +159,7 @@ public class Thread implements Runnable
/** Thread local storage. Package accessible for use by
* InheritableThreadLocal.
*/
- WeakIdentityHashMap locals;
+ final ThreadLocalMap locals;
/** The uncaught exception handler. */
UncaughtExceptionHandler exceptionHandler;
@@ -367,6 +367,7 @@ public class Thread implements Runnable
this.name = name.toString();
this.runnable = target;
this.stacksize = size;
+ this.locals = new ThreadLocalMap();
synchronized (Thread.class)
{
@@ -398,6 +399,7 @@ public class Thread implements Runnable
*/
Thread(VMThread vmThread, String name, int priority, boolean daemon)
{
+ this.locals = new ThreadLocalMap();
this.vmThread = vmThread;
this.runnable = null;
if (name == null)
@@ -1063,21 +1065,15 @@ public class Thread implements Runnable
{
group.removeThread(this);
vmThread = null;
- locals = null;
+ locals.clear();
}
/**
* Returns the map used by ThreadLocal to store the thread local values.
*/
- static Map getThreadLocals()
+ static ThreadLocalMap getThreadLocals()
{
- Thread thread = currentThread();
- Map locals = thread.locals;
- if (locals == null)
- {
- locals = thread.locals = new WeakIdentityHashMap();
- }
- return locals;
+ return currentThread().locals;
}
/**
diff --git a/libjava/classpath/java/lang/ThreadLocal.java b/libjava/classpath/java/lang/ThreadLocal.java
index 6c4ba176a41..14778c65c2f 100644
--- a/libjava/classpath/java/lang/ThreadLocal.java
+++ b/libjava/classpath/java/lang/ThreadLocal.java
@@ -37,9 +37,6 @@ exception statement from your version. */
package java.lang;
-import java.util.Map;
-
-
/**
* ThreadLocal objects have a different state associated with every
* Thread that accesses them. Every access to the ThreadLocal object
@@ -93,13 +90,31 @@ public class ThreadLocal<T>
* user. Do not expose this to the public. Package visible for use by
* InheritableThreadLocal
*/
- static final Object sentinel = new Object();
+ static final Object notFound = new Object();
+
+ /**
+ * The base for the computation of the next hash for a thread local.
+ */
+ private static int nextHashBase = 1;
+
+ /**
+ * Allocate a new hash.
+ */
+ private synchronized int computeNextHash() {
+ return nextHashBase++ * 6709;
+ }
+
+ /**
+ * Hash code computed for ThreadLocalMap
+ */
+ final int fastHash;
/**
* Creates a ThreadLocal object without associating any value to it yet.
*/
public ThreadLocal()
{
+ fastHash = computeNextHash();
}
/**
@@ -125,16 +140,16 @@ public class ThreadLocal<T>
*/
public T get()
{
- Map<ThreadLocal<T>,T> map = (Map<ThreadLocal<T>,T>) Thread.getThreadLocals();
+ ThreadLocalMap map = Thread.getThreadLocals();
// Note that we don't have to synchronize, as only this thread will
// ever modify the map.
- T value = map.get(this);
- if (value == null)
+ T value = (T) map.get(this);
+ if (value == notFound)
{
value = initialValue();
- map.put(this, (T) (value == null ? sentinel : value));
+ map.set(this, value);
}
- return value == (T) sentinel ? null : value;
+ return value;
}
/**
@@ -147,10 +162,10 @@ public class ThreadLocal<T>
*/
public void set(T value)
{
- Map map = Thread.getThreadLocals();
+ ThreadLocalMap map = Thread.getThreadLocals();
// Note that we don't have to synchronize, as only this thread will
// ever modify the map.
- map.put(this, value == null ? sentinel : value);
+ map.set(this, value);
}
/**
@@ -160,7 +175,7 @@ public class ThreadLocal<T>
*/
public void remove()
{
- Map map = Thread.getThreadLocals();
+ ThreadLocalMap map = Thread.getThreadLocals();
map.remove(this);
}
}
diff --git a/libjava/classpath/java/lang/ThreadLocalMap.java b/libjava/classpath/java/lang/ThreadLocalMap.java
new file mode 100644
index 00000000000..7f67b131183
--- /dev/null
+++ b/libjava/classpath/java/lang/ThreadLocalMap.java
@@ -0,0 +1,325 @@
+/* ThreadLocal -- a variable with a unique value per thread
+ Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * ThreadLocalMap is the basic storage for the map of ThreadLocal instance
+ * to a thread's current value.
+ *
+ * Some applications really work out ThreadLocals, leading to this
+ * optimized implementation.
+ */
+final class ThreadLocalMap
+{
+ /**
+ * The log (base 2) of the initial size of the map
+ */
+ private static final int LOG_INITIAL_SIZE = 3;
+
+ /**
+ * The maximum occupancy rate (after which we grow)
+ */
+ private static final float MAX_OCCUPANCY = 0.7f;
+
+ /**
+ * The target occupancy rate.
+ */
+ private static final float TARGET_OCCUPANCY = 0.5f;
+
+ /**
+ * The deleted entry sentinel value.
+ */
+ private static final Entry deletedEntry = new Entry(null);
+
+ /**
+ * Constructor
+ */
+ ThreadLocalMap()
+ {
+ /* Dummy value to ensure fast path can be optimized */
+ entries = new Entry[1];
+ hashMask = 0;
+ count = 0;
+ }
+
+ /**
+ * The map entries
+ */
+ private Entry[] entries;
+
+ /**
+ * Used for start index computation
+ */
+ private int hashMask;
+
+ /**
+ * The number of entries currently in the map
+ */
+ private int count;
+
+ /**
+ * Create or grow the table to the specified size. The size must be a
+ * power of two for the efficient mask/hash computation.
+ *
+ * @param newSize The new table size.
+ */
+ private void newEntryArray(int newSize)
+ {
+ int mask = newSize - 1;
+ Entry[] oldEntries = this.entries;
+ this.entries = new Entry[newSize];
+ this.hashMask = mask;
+
+ /* Copy old entries to new table */
+ count = 0;
+ if (oldEntries != null)
+ {
+ for(Entry e: oldEntries)
+ {
+ if (e != null)
+ {
+ ThreadLocal<?> key = e.get();
+ if (e != deletedEntry && key != null)
+ {
+ for(int i = key.fastHash & mask;; i = (i + 1) & mask)
+ {
+ if (entries[i] == null)
+ {
+ entries[i] = e;
+ count++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * We have run out of space in our locals. We use this as the
+ * trigger to attempt to find unused slots as ThreadLocals have
+ * died. If we recover any slots this way then we do not grow.
+ */
+ private void overflow()
+ {
+ /* First 'actual' use */
+ if (entries.length == 1)
+ {
+ newEntryArray(1 << LOG_INITIAL_SIZE);
+ return;
+ }
+
+ /* Attempt to recover unused slots */
+ int deleted = 0;
+ for(int i=0; i < entries.length; i++)
+ {
+ Entry e = entries[i];
+ if (e != null)
+ {
+ if (e == deletedEntry)
+ {
+ deleted++;
+ }
+ else if (e.get() == null)
+ {
+ entries[i] = deletedEntry;
+ deleted++;
+ }
+ }
+ }
+
+ if ((count-deleted) <= (TARGET_OCCUPANCY * entries.length))
+ {
+ /* We currently rehash by simple reallocating into a same-sized table.
+ * An alternative would be to implement a clever hashing algorithm but
+ * as this happens infrequently this seems preferred */
+ newEntryArray(entries.length);
+ return;
+ }
+
+ /* Double the size */
+ newEntryArray(entries.length << 1);
+ }
+
+ /**
+ * This is the class that is used to refer to a thread local weakly.
+ *
+ * As we want to minimize indirections we extend WeakReference.
+ */
+ static final class Entry extends WeakReference<ThreadLocal<?>> {
+ /**
+ * The value stored in this slot
+ */
+ Object value;
+
+ /**
+ * Constructor
+ */
+ Entry(ThreadLocal<?> threadLocal) {
+ super(threadLocal);
+ }
+ }
+
+ /**
+ * Gets the value associated with the ThreadLocal object for the currently
+ * executing Thread. If this is the first time the current thread has called
+ * get(), and it has not already called set(), the sentinel value is returned.
+ *
+ * @return the value of the variable in this thread, or sentinel if not present.
+ */
+ public Object get(ThreadLocal<?> key)
+ {
+ int mask = this.hashMask;
+ for(int i = key.fastHash & mask;; i = (i + 1) & mask) {
+ Entry e = entries[i];
+ if (e != null) {
+ if (e.get() == key) {
+ return e.value;
+ }
+ } else {
+ return ThreadLocal.sentinel;
+ }
+ }
+ }
+
+ /**
+ * Sets the value associated with the ThreadLocal object for the currently
+ * executing Thread. This overrides any existing value associated with the
+ * current Thread and prevents <code>initialValue()</code> from being
+ * called if this is the first access to this ThreadLocal in this Thread.
+ *
+ * @param value the value to set this thread's view of the variable to
+ */
+ public void set(ThreadLocal<?> key, Object value)
+ {
+ /* Overflow ? */
+ if ((count+1) >= (MAX_OCCUPANCY * entries.length))
+ {
+ overflow();
+ }
+
+ /* Set the entry */
+ int mask = this.hashMask;
+ for(int i = key.fastHash & mask;; i = (i + 1) & mask)
+ {
+ Entry e = entries[i];
+ if (e == null || e == deletedEntry)
+ {
+ /* Create entry */
+ if (e == null) count++;
+ entries[i] = e = new Entry(key);
+ e.value = value;
+ return;
+ }
+ else
+ {
+ ThreadLocal<?> entryKey = e.get();
+ if (entryKey == null)
+ {
+ entries[i] = deletedEntry;
+ }
+ else if (entryKey == key)
+ {
+ /* Update entry */
+ e.value = value;
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes the value associated with the ThreadLocal object for the
+ * currently executing Thread.
+ * @since 1.5
+ */
+ public void remove(ThreadLocal<?> key)
+ {
+ int mask = this.hashMask;
+ for(int i = key.fastHash & mask;; i = (i + 1) & mask)
+ {
+ Entry e = entries[i];
+ if (e != null)
+ {
+ ThreadLocal<?> entryKey = e.get();
+ if (entryKey != key)
+ {
+ if (entryKey == null) {
+ entries[i] = deletedEntry;
+ }
+ continue;
+ }
+ else
+ {
+ /* Remove from the table */
+ entries[i] = deletedEntry;
+ }
+ }
+ return;
+ }
+ }
+
+ /**
+ * Clear out the map. Done once during thread death.
+ */
+ void clear() {
+ entries = null;
+ }
+
+ /**
+ * Inherit all the InheritableThreadLocal instances from the given parent.
+ *
+ * @param parentMap The map to inherit from.
+ */
+ public void inherit(ThreadLocalMap parentMap) {
+ for(Entry e: parentMap.entries)
+ {
+ if (e != null && e != deletedEntry)
+ {
+ ThreadLocal<?> key = e.get();
+ if (key instanceof InheritableThreadLocal)
+ {
+ set(key, ((InheritableThreadLocal)key).childValue(e.value));
+ }
+ }
+ }
+ }
+}
diff --git a/libjava/classpath/java/lang/Throwable.java b/libjava/classpath/java/lang/Throwable.java
index 72f9e7f520b..f74851f0b1b 100644
--- a/libjava/classpath/java/lang/Throwable.java
+++ b/libjava/classpath/java/lang/Throwable.java
@@ -39,6 +39,8 @@ package java.lang;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Serializable;
@@ -411,7 +413,7 @@ public class Throwable implements Serializable
// different threads to get mixed up when written to the same PrintWriter.
private String stackTraceString()
{
- StringBuilder sb = new StringBuilder();
+ CPStringBuilder sb = new CPStringBuilder();
// Main stacktrace
StackTraceElement[] stack = getStackTrace();
@@ -455,7 +457,7 @@ public class Throwable implements Serializable
// Adds to the given StringBuffer a line containing the name and
// all stacktrace elements minus the last equal ones.
- private static void stackTraceStringBuffer(StringBuilder sb, String name,
+ private static void stackTraceStringBuffer(CPStringBuilder sb, String name,
StackTraceElement[] stack, int equal)
{
String nl = StaticData.nl;
diff --git a/libjava/classpath/java/lang/reflect/AccessibleObject.java b/libjava/classpath/java/lang/reflect/AccessibleObject.java
index fd46a53dc8c..328f81d7933 100644
--- a/libjava/classpath/java/lang/reflect/AccessibleObject.java
+++ b/libjava/classpath/java/lang/reflect/AccessibleObject.java
@@ -160,21 +160,72 @@ public class AccessibleObject
this.flag = flag;
}
+ /**
+ * <p>
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ * </p>
+ * <p>
+ * <strong>This method must be overridden by subclasses to provide
+ * appropriate behaviour.</strong>
+ * </p>
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
{
throw new AssertionError("Subclass must override this method");
}
+ /**
+ * Returns all annotations associated with the element. If there are
+ * no annotations associated with the element, then a zero-length array
+ * will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of the
+ * element, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return this element's annotations.
+ */
public Annotation[] getAnnotations()
{
return getDeclaredAnnotations();
}
+ /**
+ * <p>
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ * </p>
+ * <p>
+ * <strong>This method must be overridden by subclasses to provide
+ * appropriate behaviour.</strong>
+ * </p>
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
public Annotation[] getDeclaredAnnotations()
{
throw new AssertionError("Subclass must override this method");
}
+ /**
+ * Returns true if an annotation for the specified type is associated
+ * with the element. This is primarily a short-hand for using marker
+ * annotations.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return true if an annotation exists for the specified type.
+ * @since 1.5
+ */
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
{
return getAnnotation(annotationClass) != null;
diff --git a/libjava/classpath/java/lang/reflect/Constructor.java b/libjava/classpath/java/lang/reflect/Constructor.java
new file mode 100644
index 00000000000..d9b7e831216
--- /dev/null
+++ b/libjava/classpath/java/lang/reflect/Constructor.java
@@ -0,0 +1,453 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+ Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Constructor class represents a constructor of a class. It also allows
+ * dynamic creation of an object, via reflection. Invocation on Constructor
+ * objects knows how to do widening conversions, but throws
+ * {@link IllegalArgumentException} if a narrowing conversion would be
+ * necessary. You can query for information on this Constructor regardless
+ * of location, but construction access may be limited by Java language
+ * access controls. If you can't do it in the compiler, you can't normally
+ * do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getDeclaredConstructors()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Constructor<T>
+ extends AccessibleObject
+ implements GenericDeclaration, Member
+{
+ private static final int CONSTRUCTOR_MODIFIERS
+ = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+ private MethodSignatureParser p;
+
+ VMConstructor cons;
+
+ /**
+ * This class is uninstantiable outside this package.
+ */
+ Constructor(VMConstructor cons)
+ {
+ this.cons = cons;
+ cons.cons = this;
+ }
+
+ private Constructor()
+ {
+ }
+
+ /**
+ * Gets the class that declared this constructor.
+ * @return the class that declared this member
+ */
+ public Class<T> getDeclaringClass()
+ {
+ // Inescapable as the VM layer is 1.4 based.
+ @SuppressWarnings("unchecked")
+ Class<T> declClass = (Class<T>) cons.getDeclaringClass();
+ return declClass;
+ }
+
+ /**
+ * Gets the name of this constructor (the non-qualified name of the class
+ * it was declared in).
+ * @return the name of this constructor
+ */
+ public String getName()
+ {
+ return cons.getDeclaringClass().getName();
+ }
+
+ /**
+ * Gets the modifiers this constructor uses. Use the <code>Modifier</code>
+ * class to interpret the values. A constructor can only have a subset of the
+ * following modifiers: public, private, protected.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return cons.getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+ }
+
+ /**
+ * Return true if this constructor is synthetic, false otherwise.
+ * A synthetic member is one which is created by the compiler,
+ * and which does not appear in the user's source code.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (cons.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs constructor, that is if
+ * the constructor takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (cons.getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Get the parameter list for this constructor, in declaration order. If the
+ * constructor takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the constructor's parameters
+ */
+ public Class<?>[] getParameterTypes()
+ {
+ return (Class<?>[]) cons.getParameterTypes();
+ }
+
+ /**
+ * Get the exception types this constructor says it throws, in no particular
+ * order. If the constructor has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the constructor's throws clause
+ */
+ public Class<?>[] getExceptionTypes()
+ {
+ return (Class<?>[]) cons.getExceptionTypes();
+ }
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Constructors are semantically equivalent if they have the same
+ * declaring class and the same parameter list. This ignores different
+ * exception clauses, but since you can't create a Method except through the
+ * VM, this is just the == relation.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not.
+ */
+ public boolean equals(Object o)
+ {
+ return cons.equals(o);
+ }
+
+ /**
+ * Get the hash code for the Constructor. The Constructor hash code is the
+ * hash code of the declaring class's name.
+ *
+ * @return the hash code for the object
+ */
+ public int hashCode()
+ {
+ return getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Constructor. A Constructor's String
+ * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
+ * throws &lt;exceptions&gt;", where everything after ')' is omitted if
+ * there are no exceptions.<br> Example:
+ * <code>public java.io.FileInputStream(java.lang.Runnable)
+ * throws java.io.FileNotFoundException</code>
+ *
+ * @return the String representation of the Constructor
+ */
+ public String toString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ CPStringBuilder sb = new CPStringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getDeclaringClass().getName()).append('(');
+ Class[] c = getParameterTypes();
+ if (c.length > 0)
+ {
+ sb.append(ClassHelper.getUserName(c[0]));
+ for (int i = 1; i < c.length; i++)
+ sb.append(',').append(ClassHelper.getUserName(c[i]));
+ }
+ sb.append(')');
+ c = getExceptionTypes();
+ if (c.length > 0)
+ {
+ sb.append(" throws ").append(c[0].getName());
+ for (int i = 1; i < c.length; i++)
+ sb.append(',').append(c[i].getName());
+ }
+ return sb.toString();
+ }
+
+ static <X extends GenericDeclaration>
+ void addTypeParameters(CPStringBuilder sb, TypeVariable<X>[] typeArgs)
+ {
+ if (typeArgs.length == 0)
+ return;
+ sb.append('<');
+ for (int i = 0; i < typeArgs.length; ++i)
+ {
+ if (i > 0)
+ sb.append(',');
+ sb.append(typeArgs[i]);
+ }
+ sb.append("> ");
+ }
+
+ public String toGenericString()
+ {
+ CPStringBuilder sb = new CPStringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ addTypeParameters(sb, getTypeParameters());
+ sb.append(getDeclaringClass().getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; ++i)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Create a new instance by invoking the constructor. Arguments are
+ * automatically unwrapped and widened, if needed.<p>
+ *
+ * If this class is abstract, you will get an
+ * <code>InstantiationException</code>. If the constructor takes 0
+ * arguments, you may use null or a 0-length array for <code>args</code>.<p>
+ *
+ * If this Constructor enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not create this object in similar compiled code. If the class
+ * is uninitialized, you trigger class initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Then, the constructor is invoked. If it completes normally, the return
+ * value will be the new object. If it completes abruptly, the exception is
+ * wrapped in an <code>InvocationTargetException</code>.
+ *
+ * @param args the arguments to the constructor
+ * @return the newly created object
+ * @throws IllegalAccessException if the constructor could not normally be
+ * called by the Java code (i.e. it is not public)
+ * @throws IllegalArgumentException if the number of arguments is incorrect;
+ * or if the arguments types are wrong even with a widening
+ * conversion
+ * @throws InstantiationException if the class is abstract
+ * @throws InvocationTargetException if the constructor throws an exception
+ * @throws ExceptionInInitializerError if construction triggered class
+ * initialization, which then failed
+ */
+ public T newInstance(Object... args)
+ throws InstantiationException, IllegalAccessException,
+ InvocationTargetException
+ {
+ // Inescapable as the VM layer is 1.4 based.
+ @SuppressWarnings("unchecked")
+ T ins = (T) cons.construct(args);
+ return ins;
+ }
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor has no type
+ * variables.
+ *
+ * @return the type variables associated with this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Constructor<T>>[] getTypeParameters()
+ {
+ if (p == null)
+ {
+ String sig = cons.getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ p = new MethodSignatureParser(this, sig);
+ }
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ if (p == null)
+ {
+ String sig = cons.getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ p = new MethodSignatureParser(this, sig);
+ }
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this constructor, in declaration order.
+ * An array of size zero is returned if this constructor takes no
+ * parameters.
+ *
+ * @return a list of the types of the constructor's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ if (p == null)
+ {
+ String sig = cons.getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ p = new MethodSignatureParser(this, sig);
+ }
+ return p.getGenericParameterTypes();
+ }
+
+ /**
+ * <p>
+ * Return an array of arrays representing the annotations on each
+ * of the constructor's parameters. The outer array is aligned against
+ * the parameters of the constructors and is thus equal in length to
+ * the number of parameters (thus having a length zero if there are none).
+ * Each array element in the outer array contains an inner array which
+ * holds the annotations. This array has a length of zero if the parameter
+ * has no annotations.
+ * </p>
+ * <p>
+ * The returned annotations are serialized. Changing the annotations has
+ * no affect on the return value of future calls to this method.
+ * </p>
+ *
+ * @return an array of arrays which represents the annotations used on the
+ * parameters of this constructor. The order of the array elements
+ * matches the declaration order of the parameters.
+ * @since 1.5
+ */
+ public Annotation[][] getParameterAnnotations()
+ {
+ return cons.getParameterAnnotations();
+ }
+
+ /**
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ // Inescapable as the VM layer is 1.4 based.
+ @SuppressWarnings("unchecked")
+ T ann = (T) cons.getAnnotation(annotationClass);
+ return ann;
+ }
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations()
+ {
+ return cons.getDeclaredAnnotations();
+ }
+
+}
diff --git a/libjava/classpath/java/lang/reflect/Field.java b/libjava/classpath/java/lang/reflect/Field.java
new file mode 100644
index 00000000000..b9d92884564
--- /dev/null
+++ b/libjava/classpath/java/lang/reflect/Field.java
@@ -0,0 +1,735 @@
+/* java.lang.reflect.Field - reflection of Java fields
+ Copyright (C) 1998, 2001, 2005, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Field class represents a member variable of a class. It also allows
+ * dynamic access to a member, via reflection. This works for both
+ * static and instance fields. Operations on Field objects know how to
+ * do widening conversions, but throw {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Field regardless of location, but get and set access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see Class#getField(String)
+ * @see Class#getDeclaredField(String)
+ * @see Class#getFields()
+ * @see Class#getDeclaredFields()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Field
+extends AccessibleObject implements Member
+{
+ static final int FIELD_MODIFIERS
+ = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+ | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+ | Modifier.VOLATILE;
+
+ private FieldSignatureParser p;
+
+ VMField f;
+
+ /**
+ * This class is uninstantiable outside the package.
+ */
+ Field(VMField f)
+ {
+ this.f = f;
+ f.f = this;
+ }
+
+ /**
+ * Gets the class that declared this field, or the class where this field
+ * is a non-inherited member.
+ * @return the class that declared this member
+ */
+ public Class<?> getDeclaringClass()
+ {
+ return (Class<?>) f.getDeclaringClass();
+ }
+
+ /**
+ * Gets the name of this field.
+ * @return the name of this field
+ */
+ public String getName()
+ {
+ return f.getName();
+ }
+
+ /**
+ * Gets the modifiers this field uses. Use the <code>Modifier</code>
+ * class to interpret the values. A field can only have a subset of the
+ * following modifiers: public, private, protected, static, final,
+ * transient, and volatile.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return f.getModifiersInternal() & FIELD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this field is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (f.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this field represents an enum constant,
+ * false otherwise.
+ * @since 1.5
+ */
+ public boolean isEnumConstant()
+ {
+ return (f.getModifiersInternal() & Modifier.ENUM) != 0;
+ }
+
+ /**
+ * Gets the type of this field.
+ * @return the type of this field
+ */
+ public Class<?> getType()
+ {
+ return f.getType();
+ }
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Fields are semantically equivalent if they have the same declaring
+ * class, name, and type. Since you can't creat a Field except through
+ * the VM, this is just the == relation.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals(Object o)
+ {
+ return f.equals(o);
+ }
+
+ /**
+ * Get the hash code for the Field. The Field hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
+ *
+ * @return the hash code for the object.
+ */
+ public int hashCode()
+ {
+ return f.getDeclaringClass().getName().hashCode() ^ f.getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Field. A Field's String
+ * representation is "&lt;modifiers&gt; &lt;type&gt;
+ * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
+ * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+ *
+ * @return the String representation of the Field
+ */
+ public String toString()
+ {
+ // 64 is a reasonable buffer initial size for field
+ CPStringBuilder sb = new CPStringBuilder(64);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(ClassHelper.getUserName(getType())).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName());
+ return sb.toString();
+ }
+
+ public String toGenericString()
+ {
+ CPStringBuilder sb = new CPStringBuilder(64);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getGenericType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName());
+ return sb.toString();
+ }
+
+ /**
+ * Get the value of this Field. If it is primitive, it will be wrapped
+ * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. If the field
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is accessed, and primitives are wrapped (but not
+ * necessarily in new objects). This method accesses the field of the
+ * declaring class, even if the instance passed in belongs to a subclass
+ * which declares another field to hide this one.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>o</code> is not an instance of
+ * the class or interface declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #getBoolean(Object)
+ * @see #getByte(Object)
+ * @see #getChar(Object)
+ * @see #getShort(Object)
+ * @see #getInt(Object)
+ * @see #getLong(Object)
+ * @see #getFloat(Object)
+ * @see #getDouble(Object)
+ */
+ public Object get(Object o)
+ throws IllegalAccessException
+ {
+ return f.get(o);
+ }
+
+ /**
+ * Get the value of this boolean Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public boolean getBoolean(Object o)
+ throws IllegalAccessException
+ {
+ return f.getBoolean(o);
+ }
+
+ /**
+ * Get the value of this byte Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public byte getByte(Object o)
+ throws IllegalAccessException
+ {
+ return f.getByte(o);
+ }
+
+ /**
+ * Get the value of this Field as a char. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char field of
+ * <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public char getChar(Object o)
+ throws IllegalAccessException
+ {
+ return f.getChar(o);
+ }
+
+ /**
+ * Get the value of this Field as a short. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte or short
+ * field of <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public short getShort(Object o)
+ throws IllegalAccessException
+ {
+ return f.getShort(o);
+ }
+
+ /**
+ * Get the value of this Field as an int. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, or
+ * int field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public int getInt(Object o)
+ throws IllegalAccessException
+ {
+ return f.getInt(o);
+ }
+
+ /**
+ * Get the value of this Field as a long. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * or long field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public long getLong(Object o)
+ throws IllegalAccessException
+ {
+ return f.getLong(o);
+ }
+
+ /**
+ * Get the value of this Field as a float. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, or float field of <code>o</code>, or if <code>o</code> is
+ * not an instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public float getFloat(Object o)
+ throws IllegalAccessException
+ {
+ return f.getFloat(o);
+ }
+
+ /**
+ * Get the value of this Field as a double. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, float, or double field of <code>o</code>, or if
+ * <code>o</code> is not an instance of the declaring class of this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public double getDouble(Object o)
+ throws IllegalAccessException
+ {
+ return f.getDouble(o);
+ }
+
+ /**
+ * Set the value of this Field. If it is a primitive field, the value
+ * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. This also
+ * occurs whether or not there is access control if the field is final.
+ * If the field is primitive, and unwrapping your argument fails, you will
+ * get an <code>IllegalArgumentException</code>; likewise, this error
+ * happens if <code>value</code> cannot be cast to the correct object type.
+ * If the field is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is set with the widened value. This method accesses
+ * the field of the declaring class, even if the instance passed in belongs
+ * to a subclass which declares another field to hide this one.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>value</code> cannot be
+ * converted by a widening conversion to the underlying type of
+ * the Field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #setBoolean(Object, boolean)
+ * @see #setByte(Object, byte)
+ * @see #setChar(Object, char)
+ * @see #setShort(Object, short)
+ * @see #setInt(Object, int)
+ * @see #setLong(Object, long)
+ * @see #setFloat(Object, float)
+ * @see #setDouble(Object, double)
+ */
+ public void set(Object o, Object value)
+ throws IllegalAccessException
+ {
+ f.set(o, value);
+ }
+
+ /**
+ * Set this boolean Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setBoolean(Object o, boolean value)
+ throws IllegalAccessException
+ {
+ f.setBoolean(o, value);
+ }
+
+ /**
+ * Set this byte Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setByte(Object o, byte value)
+ throws IllegalAccessException
+ {
+ f.setByte(o, value);
+ }
+
+ /**
+ * Set this char Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setChar(Object o, char value)
+ throws IllegalAccessException
+ {
+ f.setChar(o, value);
+ }
+
+ /**
+ * Set this short Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setShort(Object o, short value)
+ throws IllegalAccessException
+ {
+ f.setShort(o, value);
+ }
+
+ /**
+ * Set this int Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not an int, long, float, or
+ * double field, or if <code>o</code> is not an instance of the
+ * class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setInt(Object o, int value)
+ throws IllegalAccessException
+ {
+ f.setInt(o, value);
+ }
+
+ /**
+ * Set this long Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a long, float, or double
+ * field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setLong(Object o, long value)
+ throws IllegalAccessException
+ {
+ f.setLong(o, value);
+ }
+
+ /**
+ * Set this float Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a float or long field, or
+ * if <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setFloat(Object o, float value)
+ throws IllegalAccessException
+ {
+ f.setFloat(o, value);
+ }
+
+ /**
+ * Set this double Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a double field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setDouble(Object o, double value)
+ throws IllegalAccessException
+ {
+ f.setDouble(o, value);
+ }
+
+ /**
+ * Return the generic type of the field. If the field type is not a generic
+ * type, the method returns the same as <code>getType()</code>.
+ *
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericType()
+ {
+ if (p == null)
+ {
+ String signature = f.getSignature();
+ if (signature == null)
+ return getType();
+ p = new FieldSignatureParser(getDeclaringClass(),
+ signature);
+ }
+ return p.getFieldType();
+ }
+
+ /**
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ // Inescapable as the VM layer is 1.4 based. T will erase to Annotation anyway.
+ @SuppressWarnings("unchecked") T ann = (T) f.getAnnotation(annotationClass);
+ return ann;
+ }
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations()
+ {
+ return f.getDeclaredAnnotations();
+ }
+
+}
diff --git a/libjava/classpath/java/lang/reflect/Method.java b/libjava/classpath/java/lang/reflect/Method.java
new file mode 100644
index 00000000000..0a532ddb6f2
--- /dev/null
+++ b/libjava/classpath/java/lang/reflect/Method.java
@@ -0,0 +1,497 @@
+/* java.lang.reflect.Method - reflection of Java methods
+ Copyright (C) 1998, 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Method class represents a member method of a class. It also allows
+ * dynamic invocation, via reflection. This works for both static and
+ * instance methods. Invocation on Method objects knows how to do
+ * widening conversions, but throws {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Method regardless of location, but invocation access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getDeclaredMethods()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Method
+extends AccessibleObject implements Member, GenericDeclaration
+{
+ private static final int METHOD_MODIFIERS
+ = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+ | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+ | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
+ private MethodSignatureParser p;
+
+ VMMethod m;
+
+ /**
+ * This class is uninstantiable outside this package.
+ */
+ Method(VMMethod m)
+ {
+ this.m = m;
+ m.m = this;
+ }
+
+ /**
+ * Gets the class that declared this method, or the class where this method
+ * is a non-inherited member.
+ * @return the class that declared this member
+ */
+ public Class<?> getDeclaringClass()
+ {
+ return (Class<?>) m.getDeclaringClass();
+ }
+
+ /**
+ * Gets the name of this method.
+ * @return the name of this method
+ */
+ public String getName()
+ {
+ return m.getName();
+ }
+
+ /**
+ * Gets the modifiers this method uses. Use the <code>Modifier</code>
+ * class to interpret the values. A method can only have a subset of the
+ * following modifiers: public, private, protected, abstract, static,
+ * final, synchronized, native, and strictfp.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return m.getModifiersInternal() & METHOD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this method is a bridge method. A bridge method
+ * is generated by the compiler in some situations involving
+ * generics and inheritance.
+ * @since 1.5
+ */
+ public boolean isBridge()
+ {
+ return (m.getModifiersInternal() & Modifier.BRIDGE) != 0;
+ }
+
+ /**
+ * Return true if this method is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (m.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs method, that is if
+ * the method takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (m.getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Gets the return type of this method.
+ * @return the type of this method
+ */
+ public Class<?> getReturnType()
+ {
+ return (Class<?>) m.getReturnType();
+ }
+
+ /**
+ * Get the parameter list for this method, in declaration order. If the
+ * method takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the method's parameters
+ */
+ public Class<?>[] getParameterTypes()
+ {
+ return (Class<?>[]) m.getParameterTypes();
+ }
+
+ /**
+ * Get the exception types this method says it throws, in no particular
+ * order. If the method has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the method's throws clause
+ */
+ public Class<?>[] getExceptionTypes()
+ {
+ return (Class<?>[]) m.getExceptionTypes();
+ }
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Methods are semantically equivalent if they have the same declaring
+ * class, name, parameter list, and return type.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals(Object o)
+ {
+ return m.equals(o);
+ }
+
+ /**
+ * Get the hash code for the Method. The Method hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
+ *
+ * @return the hash code for the object
+ */
+ public int hashCode()
+ {
+ return m.getDeclaringClass().getName().hashCode() ^ m.getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Method. A Method's String
+ * representation is "&lt;modifiers&gt; &lt;returntype&gt;
+ * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
+ * everything after ')' is omitted if there are no exceptions.<br> Example:
+ * <code>public static int run(java.lang.Runnable,int)</code>
+ *
+ * @return the String representation of the Method
+ */
+ public String toString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ CPStringBuilder sb = new CPStringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(ClassHelper.getUserName(getReturnType())).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName()).append('(');
+ Class[] c = getParameterTypes();
+ if (c.length > 0)
+ {
+ sb.append(ClassHelper.getUserName(c[0]));
+ for (int i = 1; i < c.length; i++)
+ sb.append(',').append(ClassHelper.getUserName(c[i]));
+ }
+ sb.append(')');
+ c = getExceptionTypes();
+ if (c.length > 0)
+ {
+ sb.append(" throws ").append(c[0].getName());
+ for (int i = 1; i < c.length; i++)
+ sb.append(',').append(c[i].getName());
+ }
+ return sb.toString();
+ }
+
+ public String toGenericString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ CPStringBuilder sb = new CPStringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ Constructor.addTypeParameters(sb, getTypeParameters());
+ sb.append(getGenericReturnType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Invoke the method. Arguments are automatically unwrapped and widened,
+ * and the result is automatically wrapped, if needed.<p>
+ *
+ * If the method is static, <code>o</code> will be ignored. Otherwise,
+ * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
+ * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
+ * you will get a <code>NullPointerException</code> if <code>o</code> is
+ * null, and an <code>IllegalArgumentException</code> if it is incompatible
+ * with the declaring class of the method. If the method takes 0 arguments,
+ * you may use null or a 0-length array for <code>args</code>.<p>
+ *
+ * Next, if this Method enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not acces this method in similar compiled code. If the method
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the method is invoked. If it completes normally, the return value
+ * will be null for a void method, a wrapped object for a primitive return
+ * method, or the actual return of an Object method. If it completes
+ * abruptly, the exception is wrapped in an
+ * <code>InvocationTargetException</code>.
+ *
+ * @param o the object to invoke the method on
+ * @param args the arguments to the method
+ * @return the return value of the method, wrapped in the appropriate
+ * wrapper if it is primitive
+ * @throws IllegalAccessException if the method could not normally be called
+ * by the Java code (i.e. it is not public)
+ * @throws IllegalArgumentException if the number of arguments is incorrect;
+ * if the arguments types are wrong even with a widening conversion;
+ * or if <code>o</code> is not an instance of the class or interface
+ * declaring this method
+ * @throws InvocationTargetException if the method throws an exception
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static method triggered
+ * class initialization, which then failed
+ */
+ public Object invoke(Object o, Object... args)
+ throws IllegalAccessException, InvocationTargetException
+ {
+ return m.invoke(o, args);
+ }
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Method>[] getTypeParameters()
+ {
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return (TypeVariable<Method>[]) new TypeVariable[0];
+ p = new MethodSignatureParser(this, sig);
+ }
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this method, in declaration order.
+ * An array of size zero is returned if this method declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this method.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ p = new MethodSignatureParser(this, sig);
+ }
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this method, in declaration order.
+ * An array of size zero is returned if this method takes no
+ * parameters.
+ *
+ * @return a list of the types of the method's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ p = new MethodSignatureParser(this, sig);
+ }
+ return p.getGenericParameterTypes();
+ }
+
+ /**
+ * Returns the return type of this method.
+ *
+ * @return the return type of this method
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericReturnType()
+ {
+ if (p == null)
+ {
+ String sig = m.getSignature();
+ if (sig == null)
+ return getReturnType();
+ p = new MethodSignatureParser(this, sig);
+ }
+ return p.getGenericReturnType();
+ }
+
+ /**
+ * If this method is an annotation method, returns the default
+ * value for the method. If there is no default value, or if the
+ * method is not a member of an annotation type, returns null.
+ * Primitive types are wrapped.
+ *
+ * @throws TypeNotPresentException if the method returns a Class,
+ * and the class cannot be found
+ *
+ * @since 1.5
+ */
+ public Object getDefaultValue()
+ {
+ return m.getDefaultValue();
+ }
+
+ /**
+ * <p>
+ * Return an array of arrays representing the annotations on each
+ * of the method's parameters. The outer array is aligned against
+ * the parameters of the method and is thus equal in length to
+ * the number of parameters (thus having a length zero if there are none).
+ * Each array element in the outer array contains an inner array which
+ * holds the annotations. This array has a length of zero if the parameter
+ * has no annotations.
+ * </p>
+ * <p>
+ * The returned annotations are serialized. Changing the annotations has
+ * no affect on the return value of future calls to this method.
+ * </p>
+ *
+ * @return an array of arrays which represents the annotations used on the
+ * parameters of this method. The order of the array elements
+ * matches the declaration order of the parameters.
+ * @since 1.5
+ */
+ public Annotation[][] getParameterAnnotations()
+ {
+ return m.getParameterAnnotations();
+ }
+
+ /**
+ * Returns the element's annotation for the specified annotation type,
+ * or <code>null</code> if no such annotation exists.
+ *
+ * @param annotationClass the type of annotation to look for.
+ * @return this element's annotation for the specified type, or
+ * <code>null</code> if no such annotation exists.
+ * @throws NullPointerException if the annotation class is <code>null</code>.
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+ {
+ // Inescapable as the VM layer is 1.4 based. T will erase to Annotation anyway.
+ @SuppressWarnings("unchecked")
+ T ann = (T) m.getAnnotation(annotationClass);
+ return ann;
+ }
+
+ /**
+ * Returns all annotations directly defined by the element. If there are
+ * no annotations directly associated with the element, then a zero-length
+ * array will be returned. The returned array may be modified by the client
+ * code, but this will have no effect on the annotation content of this
+ * class, and hence no effect on the return value of this method for
+ * future callers.
+ *
+ * @return the annotations directly defined by the element.
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations()
+ {
+ return m.getDeclaredAnnotations();
+ }
+
+}
diff --git a/libjava/classpath/java/lang/reflect/Modifier.java b/libjava/classpath/java/lang/reflect/Modifier.java
index 45fc4e37e69..45d9b51a75e 100644
--- a/libjava/classpath/java/lang/reflect/Modifier.java
+++ b/libjava/classpath/java/lang/reflect/Modifier.java
@@ -1,5 +1,5 @@
/* java.lang.reflect.Modifier
- Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2008 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.lang.reflect;
+import gnu.java.lang.CPStringBuilder;
+
/**
* Modifier is a helper class with static methods to determine whether an
* int returned from getModifiers() represents static, public, protected,
@@ -308,28 +310,16 @@ public class Modifier
*/
public static String toString(int mod)
{
- return toString(mod, new StringBuilder()).toString();
- }
-
- /**
- * Package helper method that can take a StringBuilder.
- * @param mod the modifier
- * @param r the StringBuilder to which the String representation is appended
- * @return r, with information appended
- */
- static StringBuilder toString(int mod, StringBuilder r)
- {
- r.append(toString(mod, new StringBuffer()));
- return r;
+ return toString(mod, new CPStringBuilder()).toString();
}
/**
- * Package helper method that can take a StringBuffer.
+ * Package helper method that can take a CPStringBuilder.
* @param mod the modifier
- * @param r the StringBuffer to which the String representation is appended
+ * @param r the CPStringBuilder to which the String representation is appended
* @return r, with information appended
*/
- static StringBuffer toString(int mod, StringBuffer r)
+ static CPStringBuilder toString(int mod, CPStringBuilder r)
{
if (isPublic(mod))
r.append("public ");
diff --git a/libjava/classpath/java/lang/reflect/Proxy.java b/libjava/classpath/java/lang/reflect/Proxy.java
index 6c1e975a287..fb2004e790b 100644
--- a/libjava/classpath/java/lang/reflect/Proxy.java
+++ b/libjava/classpath/java/lang/reflect/Proxy.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.lang.reflect;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.lang.reflect.TypeSignature;
import java.io.Serializable;
@@ -1033,7 +1035,7 @@ public class Proxy implements Serializable
code_length += 9; // new, dup_x1, swap, invokespecial, athrow
}
int handler_pc = code_length - 1;
- StringBuilder signature = new StringBuilder("(");
+ CPStringBuilder signature = new CPStringBuilder("(");
for (int j = 0; j < paramtypes.length; j++)
signature.append(TypeSignature.getEncodingOfClass(paramtypes[j]));
signature.append(")").append(TypeSignature.getEncodingOfClass(ret_type));
@@ -1492,7 +1494,7 @@ public class Proxy implements Serializable
if (i == len)
return str;
- final StringBuilder sb = new StringBuilder(str);
+ final CPStringBuilder sb = new CPStringBuilder(str);
sb.setLength(i);
for ( ; i < len; i++)
{
diff --git a/libjava/classpath/java/math/BigDecimal.java b/libjava/classpath/java/math/BigDecimal.java
index 28c4d45d3eb..eceaf8cddc2 100644
--- a/libjava/classpath/java/math/BigDecimal.java
+++ b/libjava/classpath/java/math/BigDecimal.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.math;
+import gnu.java.lang.CPStringBuilder;
+
public class BigDecimal extends Number implements Comparable<BigDecimal>
{
private BigInteger intVal;
@@ -451,7 +453,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
// val is a StringBuilder from which we'll create a BigInteger
// which will be the unscaled value for this BigDecimal
- StringBuilder val = new StringBuilder(point - start - 1);
+ CPStringBuilder val = new CPStringBuilder(point - start - 1);
if (dot != -1)
{
// If there was a decimal we must combine the two parts that
@@ -1070,7 +1072,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
boolean negative = (bigStr.charAt(0) == '-');
int point = bigStr.length() - scale - (negative ? 1 : 0);
- StringBuilder val = new StringBuilder();
+ CPStringBuilder val = new CPStringBuilder();
if (scale >= 0 && (point - 1) >= -6)
{
@@ -1137,7 +1139,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
// This is the adjusted exponent described above.
int adjExp = point - 1;
- StringBuilder val = new StringBuilder();
+ CPStringBuilder val = new CPStringBuilder();
if (scale >= 0 && adjExp >= -6)
{
@@ -1242,8 +1244,8 @@ public class BigDecimal extends Number implements Comparable<BigDecimal>
int point = bigStr.length() - scale - (negative ? 1 : 0);
- StringBuffer sb = new StringBuffer(bigStr.length() + 2
- + (point <= 0 ? (-point + 1) : 0));
+ CPStringBuilder sb = new CPStringBuilder(bigStr.length() + 2
+ + (point <= 0 ? (-point + 1) : 0));
if (point <= 0)
{
// We have to prepend zeros and a decimal point.
diff --git a/libjava/classpath/java/math/BigInteger.java b/libjava/classpath/java/math/BigInteger.java
index 3fb75ffa37b..9d7abc755ac 100644
--- a/libjava/classpath/java/math/BigInteger.java
+++ b/libjava/classpath/java/math/BigInteger.java
@@ -38,12 +38,17 @@ exception statement from your version. */
package java.math;
+import gnu.classpath.Configuration;
+
+import gnu.java.lang.CPStringBuilder;
+import gnu.java.math.GMP;
import gnu.java.math.MPN;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Random;
+import java.util.logging.Logger;
/**
* Written using on-line Java Platform 1.2 API Specification, as well
@@ -59,6 +64,8 @@ import java.util.Random;
*/
public class BigInteger extends Number implements Comparable<BigInteger>
{
+ private static final Logger log = Logger.getLogger(BigInteger.class.getName());
+
/** All integers are stored in 2's-complement form.
* If words == null, the ival is the value of this BigInteger.
* Otherwise, the first ival elements of words make the value
@@ -67,9 +74,10 @@ public class BigInteger extends Number implements Comparable<BigInteger>
private transient int[] words;
// Serialization fields.
+ // the first three, although not used in the code, are present for
+ // compatibility with older RI versions of this class. DO NOT REMOVE.
private int bitCount = -1;
private int bitLength = -1;
- private int firstNonzeroByteNum = -2;
private int lowestSetBit = -2;
private byte[] magnitude;
private int signum;
@@ -81,31 +89,52 @@ public class BigInteger extends Number implements Comparable<BigInteger>
private static final int minFixNum = -100;
private static final int maxFixNum = 1024;
private static final int numFixNum = maxFixNum-minFixNum+1;
- private static final BigInteger[] smallFixNums = new BigInteger[numFixNum];
+ private static final BigInteger[] smallFixNums;
+
+ /** The alter-ego GMP instance for this. */
+ private transient GMP mpz;
+
+ private static final boolean USING_NATIVE = Configuration.WANT_NATIVE_BIG_INTEGER
+ && initializeLibrary();
static
{
- for (int i = numFixNum; --i >= 0; )
- smallFixNums[i] = new BigInteger(i + minFixNum);
+ if (USING_NATIVE)
+ {
+ smallFixNums = null;
+ ZERO = valueOf(0L);
+ ONE = valueOf(1L);
+ TEN = valueOf(10L);
+ }
+ else
+ {
+ smallFixNums = new BigInteger[numFixNum];
+ for (int i = numFixNum; --i >= 0; )
+ smallFixNums[i] = new BigInteger(i + minFixNum);
+
+ ZERO = smallFixNums[-minFixNum];
+ ONE = smallFixNums[1 - minFixNum];
+ TEN = smallFixNums[10 - minFixNum];
+ }
}
/**
* The constant zero as a BigInteger.
* @since 1.2
*/
- public static final BigInteger ZERO = smallFixNums[0 - minFixNum];
+ public static final BigInteger ZERO;
/**
* The constant one as a BigInteger.
* @since 1.2
*/
- public static final BigInteger ONE = smallFixNums[1 - minFixNum];
+ public static final BigInteger ONE;
/**
* The constant ten as a BigInteger.
* @since 1.5
*/
- public static final BigInteger TEN = smallFixNums[10 - minFixNum];
+ public static final BigInteger TEN;
/* Rounding modes: */
private static final int FLOOR = 1;
@@ -130,19 +159,72 @@ public class BigInteger extends Number implements Comparable<BigInteger>
private BigInteger()
{
+ super();
+
+ if (USING_NATIVE)
+ mpz = new GMP();
}
/* Create a new (non-shared) BigInteger, and initialize to an int. */
private BigInteger(int value)
{
+ super();
+
ival = value;
}
- public BigInteger(String val, int radix)
+ public BigInteger(String s, int radix)
{
- BigInteger result = valueOf(val, radix);
- this.ival = result.ival;
- this.words = result.words;
+ this();
+
+ int len = s.length();
+ int i, digit;
+ boolean negative;
+ byte[] bytes;
+ char ch = s.charAt(0);
+ if (ch == '-')
+ {
+ negative = true;
+ i = 1;
+ bytes = new byte[len - 1];
+ }
+ else
+ {
+ negative = false;
+ i = 0;
+ bytes = new byte[len];
+ }
+ int byte_len = 0;
+ for ( ; i < len; i++)
+ {
+ ch = s.charAt(i);
+ digit = Character.digit(ch, radix);
+ if (digit < 0)
+ throw new NumberFormatException("Invalid character at position #" + i);
+ bytes[byte_len++] = (byte) digit;
+ }
+
+ if (USING_NATIVE)
+ {
+ bytes = null;
+ if (mpz.fromString(s, radix) != 0)
+ throw new NumberFormatException("String \"" + s
+ + "\" is NOT a valid number in base "
+ + radix);
+ }
+ else
+ {
+ BigInteger result;
+ // Testing (len < MPN.chars_per_word(radix)) would be more accurate,
+ // but slightly more expensive, for little practical gain.
+ if (len <= 15 && radix <= 16)
+ result = valueOf(Long.parseLong(s, radix));
+ else
+ result = valueOf(bytes, byte_len, negative, radix);
+
+ this.ival = result.ival;
+ this.words = result.words;
+ }
}
public BigInteger(String val)
@@ -153,17 +235,26 @@ public class BigInteger extends Number implements Comparable<BigInteger>
/* Create a new (non-shared) BigInteger, and initialize from a byte array. */
public BigInteger(byte[] val)
{
+ this();
+
if (val == null || val.length < 1)
throw new NumberFormatException();
- words = byteArrayToIntArray(val, val[0] < 0 ? -1 : 0);
- BigInteger result = make(words, words.length);
- this.ival = result.ival;
- this.words = result.words;
+ if (USING_NATIVE)
+ mpz.fromByteArray(val);
+ else
+ {
+ words = byteArrayToIntArray(val, val[0] < 0 ? -1 : 0);
+ BigInteger result = make(words, words.length);
+ this.ival = result.ival;
+ this.words = result.words;
+ }
}
public BigInteger(int signum, byte[] magnitude)
{
+ this();
+
if (magnitude == null || signum > 1 || signum < -1)
throw new NumberFormatException();
@@ -177,18 +268,25 @@ public class BigInteger extends Number implements Comparable<BigInteger>
return;
}
- // Magnitude is always positive, so don't ever pass a sign of -1.
- words = byteArrayToIntArray(magnitude, 0);
- BigInteger result = make(words, words.length);
- this.ival = result.ival;
- this.words = result.words;
+ if (USING_NATIVE)
+ mpz.fromSignedMagnitude(magnitude, signum == -1);
+ else
+ {
+ // Magnitude is always positive, so don't ever pass a sign of -1.
+ words = byteArrayToIntArray(magnitude, 0);
+ BigInteger result = make(words, words.length);
+ this.ival = result.ival;
+ this.words = result.words;
- if (signum < 0)
- setNegative();
+ if (signum < 0)
+ setNegative();
+ }
}
public BigInteger(int numBits, Random rnd)
{
+ this();
+
if (numBits < 0)
throw new IllegalArgumentException();
@@ -197,6 +295,22 @@ public class BigInteger extends Number implements Comparable<BigInteger>
private void init(int numBits, Random rnd)
{
+ if (USING_NATIVE)
+ {
+ int length = (numBits + 7) / 8;
+ byte[] magnitude = new byte[length];
+ rnd.nextBytes(magnitude);
+ int discardedBitCount = numBits % 8;
+ if (discardedBitCount != 0)
+ {
+ discardedBitCount = 8 - discardedBitCount;
+ magnitude[0] = (byte)((magnitude[0] & 0xFF) >>> discardedBitCount);
+ }
+ mpz.fromSignedMagnitude(magnitude, false);
+ magnitude = null;
+ return;
+ }
+
int highbits = numBits & 31;
// minimum number of bytes to store the above number of bits
int highBitByteCount = (highbits + 7) / 8;
@@ -235,20 +349,23 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger(int bitLength, int certainty, Random rnd)
{
- this(bitLength, rnd);
+ this();
- // Keep going until we find a probable prime.
- BigInteger result;
+ BigInteger result = new BigInteger();
while (true)
{
- // ...but first ensure that BI has bitLength bits
- result = setBit(bitLength - 1);
+ result.init(bitLength, rnd);
+ result = result.setBit(bitLength - 1);
+ if (result.isProbablePrime(certainty))
+ break;
+ }
+
+ if (USING_NATIVE)
+ mpz.fromBI(result.mpz);
+ else
+ {
this.ival = result.ival;
this.words = result.words;
- if (isProbablePrime(certainty))
- return;
-
- init(bitLength, rnd);
}
}
@@ -272,6 +389,13 @@ public class BigInteger extends Number implements Comparable<BigInteger>
/** Return a (possibly-shared) BigInteger with a given long value. */
public static BigInteger valueOf(long val)
{
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ result.mpz.fromLong(val);
+ return result;
+ }
+
if (val >= minFixNum && val <= maxFixNum)
return smallFixNums[(int) val - minFixNum];
int i = (int) val;
@@ -284,6 +408,31 @@ public class BigInteger extends Number implements Comparable<BigInteger>
return result;
}
+ /**
+ * @return <code>true</code> if the GMP-based native implementation library
+ * was successfully loaded. Returns <code>false</code> otherwise.
+ */
+ private static boolean initializeLibrary()
+ {
+ boolean result;
+ try
+ {
+ System.loadLibrary("javamath");
+ GMP.natInitializeLibrary();
+ result = true;
+ }
+ catch (Throwable x)
+ {
+ result = false;
+ if (Configuration.DEBUG)
+ {
+ log.info("Unable to use native BigInteger: " + x);
+ log.info("Will use a pure Java implementation instead");
+ }
+ }
+ return result;
+ }
+
/** Make a canonicalized BigInteger from an array of words.
* The array may be reused (without copying). */
private static BigInteger make(int[] words, int len)
@@ -374,6 +523,9 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public int signum()
{
+ if (USING_NATIVE)
+ return mpz.compare(ZERO.mpz);
+
if (ival == 0 && words == null)
return 0;
int top = words == null ? ival : words[ival-1];
@@ -382,6 +534,12 @@ public class BigInteger extends Number implements Comparable<BigInteger>
private static int compareTo(BigInteger x, BigInteger y)
{
+ if (USING_NATIVE)
+ {
+ int dummy = y.signum; // force NPE check
+ return x.mpz.compare(y.mpz);
+ }
+
if (x.words == null && y.words == null)
return x.ival < y.ival ? -1 : x.ival > y.ival ? 1 : 0;
boolean x_negative = x.isNegative();
@@ -586,11 +744,27 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger add(BigInteger val)
{
+ if (USING_NATIVE)
+ {
+ int dummy = val.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.add(val.mpz, result.mpz);
+ return result;
+ }
+
return add(this, val, 1);
}
public BigInteger subtract(BigInteger val)
{
+ if (USING_NATIVE)
+ {
+ int dummy = val.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.subtract(val.mpz, result.mpz);
+ return result;
+ }
+
return add(this, val, -1);
}
@@ -672,6 +846,14 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger multiply(BigInteger y)
{
+ if (USING_NATIVE)
+ {
+ int dummy = y.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.multiply(y.mpz, result.mpz);
+ return result;
+ }
+
return times(this, y);
}
@@ -947,6 +1129,16 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger divide(BigInteger val)
{
+ if (USING_NATIVE)
+ {
+ if (val.compareTo(ZERO) == 0)
+ throw new ArithmeticException("divisor is zero");
+
+ BigInteger result = new BigInteger();
+ mpz.quotient(val.mpz, result.mpz);
+ return result;
+ }
+
if (val.isZero())
throw new ArithmeticException("divisor is zero");
@@ -957,6 +1149,16 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger remainder(BigInteger val)
{
+ if (USING_NATIVE)
+ {
+ if (val.compareTo(ZERO) == 0)
+ throw new ArithmeticException("divisor is zero");
+
+ BigInteger result = new BigInteger();
+ mpz.remainder(val.mpz, result.mpz);
+ return result;
+ }
+
if (val.isZero())
throw new ArithmeticException("divisor is zero");
@@ -967,6 +1169,17 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger[] divideAndRemainder(BigInteger val)
{
+ if (USING_NATIVE)
+ {
+ if (val.compareTo(ZERO) == 0)
+ throw new ArithmeticException("divisor is zero");
+
+ BigInteger q = new BigInteger();
+ BigInteger r = new BigInteger();
+ mpz.quotientAndRemainder(val.mpz, q.mpz, r.mpz);
+ return new BigInteger[] { q, r };
+ }
+
if (val.isZero())
throw new ArithmeticException("divisor is zero");
@@ -981,6 +1194,17 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger mod(BigInteger m)
{
+ if (USING_NATIVE)
+ {
+ int dummy = m.signum; // force NPE check
+ if (m.compareTo(ZERO) < 1)
+ throw new ArithmeticException("non-positive modulus");
+
+ BigInteger result = new BigInteger();
+ mpz.modulo(m.mpz, result.mpz);
+ return result;
+ }
+
if (m.isNegative() || m.isZero())
throw new ArithmeticException("non-positive modulus");
@@ -1000,6 +1224,14 @@ public class BigInteger extends Number implements Comparable<BigInteger>
return ONE;
throw new ArithmeticException("negative exponent");
}
+
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ mpz.pow(exponent, result.mpz);
+ return result;
+ }
+
if (isZero())
return this;
int plen = words == null ? 1 : ival; // Length of pow2.
@@ -1097,6 +1329,17 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger modInverse(BigInteger y)
{
+ if (USING_NATIVE)
+ {
+ int dummy = y.signum; // force NPE check
+ if (mpz.compare(ZERO.mpz) < 1)
+ throw new ArithmeticException("non-positive modulo");
+
+ BigInteger result = new BigInteger();
+ mpz.modInverse(y.mpz, result.mpz);
+ return result;
+ }
+
if (y.isNegative() || y.isZero())
throw new ArithmeticException("non-positive modulo");
@@ -1175,6 +1418,17 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger modPow(BigInteger exponent, BigInteger m)
{
+ if (USING_NATIVE)
+ {
+ int dummy = exponent.signum; // force NPE check
+ if (m.mpz.compare(ZERO.mpz) < 1)
+ throw new ArithmeticException("non-positive modulo");
+
+ BigInteger result = new BigInteger();
+ mpz.modPow(exponent.mpz, m.mpz, result.mpz);
+ return result;
+ }
+
if (m.isNegative() || m.isZero())
throw new ArithmeticException("non-positive modulo");
@@ -1228,6 +1482,14 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger gcd(BigInteger y)
{
+ if (USING_NATIVE)
+ {
+ int dummy = y.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.gcd(y.mpz, result.mpz);
+ return result;
+ }
+
int xval = ival;
int yval = y.ival;
if (words == null)
@@ -1281,6 +1543,9 @@ public class BigInteger extends Number implements Comparable<BigInteger>
if (certainty < 1)
return true;
+ if (USING_NATIVE)
+ return mpz.testPrimality(certainty) != 0;
+
/** We'll use the Rabin-Miller algorithm for doing a probabilistic
* primality test. It is fast, easy and has faster decreasing odds of a
* composite passing than with other tests. This means that this
@@ -1460,15 +1725,41 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger shiftLeft(int n)
{
+ if (n == 0)
+ return this;
+
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ if (n < 0)
+ mpz.shiftRight(-n, result.mpz);
+ else
+ mpz.shiftLeft(n, result.mpz);
+ return result;
+ }
+
return shift(this, n);
}
public BigInteger shiftRight(int n)
{
+ if (n == 0)
+ return this;
+
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ if (n < 0)
+ mpz.shiftLeft(-n, result.mpz);
+ else
+ mpz.shiftRight(n, result.mpz);
+ return result;
+ }
+
return shift(this, -n);
}
- private void format(int radix, StringBuffer buffer)
+ private void format(int radix, CPStringBuilder buffer)
{
if (words == null)
buffer.append(Integer.toString(ival, radix));
@@ -1537,18 +1828,27 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public String toString(int radix)
{
+ if (USING_NATIVE)
+ return mpz.toString(radix);
+
if (words == null)
return Integer.toString(ival, radix);
if (ival <= 2)
return Long.toString(longValue(), radix);
int buf_size = ival * (MPN.chars_per_word(radix) + 1);
- StringBuffer buffer = new StringBuffer(buf_size);
+ CPStringBuilder buffer = new CPStringBuilder(buf_size);
format(radix, buffer);
return buffer.toString();
}
public int intValue()
{
+ if (USING_NATIVE)
+ {
+ int result = mpz.absIntValue();
+ return mpz.compare(ZERO.mpz) < 0 ? - result : result;
+ }
+
if (words == null)
return ival;
return words[0];
@@ -1556,6 +1856,15 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public long longValue()
{
+ if (USING_NATIVE)
+ {
+ long result;
+ result = (abs().shiftRight(32)).mpz.absIntValue();
+ result <<= 32;
+ result |= mpz.absIntValue() & 0xFFFFFFFFL;
+ return this.compareTo(ZERO) < 0 ? - result : result;
+ }
+
if (words == null)
return ival;
if (ival == 1)
@@ -1566,12 +1875,25 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public int hashCode()
{
// FIXME: May not match hashcode of JDK.
+ if (USING_NATIVE)
+ {
+ // TODO: profile to decide whether to make it native
+ byte[] bytes = this.toByteArray();
+ int result = 0;
+ for (int i = 0; i < bytes.length; i++)
+ result ^= (bytes[i] & 0xFF) << (8 * (i % 4));
+ return result;
+ }
+
return words == null ? ival : (words[0] + words[ival - 1]);
}
/* Assumes x and y are both canonicalized. */
private static boolean equals(BigInteger x, BigInteger y)
{
+ if (USING_NATIVE)
+ return x.mpz.compare(y.mpz) == 0;
+
if (x.words == null && y.words == null)
return x.ival == y.ival;
if (x.words == null || y.words == null || x.ival != y.ival)
@@ -1592,43 +1914,6 @@ public class BigInteger extends Number implements Comparable<BigInteger>
return equals(this, (BigInteger) obj);
}
- private static BigInteger valueOf(String s, int radix)
- throws NumberFormatException
- {
- int len = s.length();
- // Testing (len < MPN.chars_per_word(radix)) would be more accurate,
- // but slightly more expensive, for little practical gain.
- if (len <= 15 && radix <= 16)
- return valueOf(Long.parseLong(s, radix));
-
- int i, digit;
- boolean negative;
- byte[] bytes;
- char ch = s.charAt(0);
- if (ch == '-')
- {
- negative = true;
- i = 1;
- bytes = new byte[len - 1];
- }
- else
- {
- negative = false;
- i = 0;
- bytes = new byte[len];
- }
- int byte_len = 0;
- for ( ; i < len; i++)
- {
- ch = s.charAt(i);
- digit = Character.digit(ch, radix);
- if (digit < 0)
- throw new NumberFormatException();
- bytes[byte_len++] = (byte) digit;
- }
- return valueOf(bytes, byte_len, negative, radix);
- }
-
private static BigInteger valueOf(byte[] digits, int byte_len,
boolean negative, int radix)
{
@@ -1646,6 +1931,9 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public double doubleValue()
{
+ if (USING_NATIVE)
+ return mpz.doubleValue();
+
if (words == null)
return (double) ival;
if (ival <= 2)
@@ -1827,6 +2115,13 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger abs()
{
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ mpz.abs(result.mpz);
+ return result;
+ }
+
return abs(this);
}
@@ -1841,6 +2136,13 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public BigInteger negate()
{
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ mpz.negate(result.mpz);
+ return result;
+ }
+
return neg(this);
}
@@ -1849,6 +2151,9 @@ public class BigInteger extends Number implements Comparable<BigInteger>
*/
public int bitLength()
{
+ if (USING_NATIVE)
+ return mpz.bitLength();
+
if (words == null)
return MPN.intLength(ival);
return MPN.intLength(words, ival);
@@ -1856,6 +2161,25 @@ public class BigInteger extends Number implements Comparable<BigInteger>
public byte[] toByteArray()
{
+ if (signum() == 0)
+ return new byte[1];
+
+ if (USING_NATIVE)
+ {
+ // the minimal number of bytes required to represent the MPI is function
+ // of (a) its bit-length, and (b) its sign. only when this MPI is both
+ // positive, and its bit-length is a multiple of 8 do we add one zero
+ // bit for its sign. we do this so if we construct a new MPI from the
+ // resulting byte array, we wouldn't mistake a positive number, whose
+ // bit-length is a multiple of 8, for a similar-length negative one.
+ int bits = bitLength();
+ if (bits % 8 == 0 || this.signum() == 1)
+ bits++;
+ byte[] bytes = new byte[(bits + 7) / 8];
+ mpz.toByteArray(bytes);
+ return bytes;
+ }
+
// Determine number of bytes needed. The method bitlength returns
// the size without the sign bit, so add one bit for that and then
// add 7 more to emulate the ceil function using integer math.
@@ -2112,6 +2436,14 @@ public class BigInteger extends Number implements Comparable<BigInteger>
/** Return the logical (bit-wise) "and" of two BigIntegers. */
public BigInteger and(BigInteger y)
{
+ if (USING_NATIVE)
+ {
+ int dummy = y.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.and(y.mpz, result.mpz);
+ return result;
+ }
+
if (y.words == null)
return and(this, y.ival);
else if (words == null)
@@ -2135,23 +2467,54 @@ public class BigInteger extends Number implements Comparable<BigInteger>
/** Return the logical (bit-wise) "(inclusive) or" of two BigIntegers. */
public BigInteger or(BigInteger y)
{
+ if (USING_NATIVE)
+ {
+ int dummy = y.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.or(y.mpz, result.mpz);
+ return result;
+ }
+
return bitOp(7, this, y);
}
/** Return the logical (bit-wise) "exclusive or" of two BigIntegers. */
public BigInteger xor(BigInteger y)
{
+ if (USING_NATIVE)
+ {
+ int dummy = y.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.xor(y.mpz, result.mpz);
+ return result;
+ }
+
return bitOp(6, this, y);
}
/** Return the logical (bit-wise) negation of a BigInteger. */
public BigInteger not()
{
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ mpz.not(result.mpz);
+ return result;
+ }
+
return bitOp(12, this, ZERO);
}
public BigInteger andNot(BigInteger val)
{
+ if (USING_NATIVE)
+ {
+ int dummy = val.signum; // force NPE check
+ BigInteger result = new BigInteger();
+ mpz.andNot(val.mpz, result.mpz);
+ return result;
+ }
+
return and(val.not());
}
@@ -2160,6 +2523,13 @@ public class BigInteger extends Number implements Comparable<BigInteger>
if (n < 0)
throw new ArithmeticException();
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ mpz.setBit(n, false, result.mpz);
+ return result;
+ }
+
return and(ONE.shiftLeft(n).not());
}
@@ -2168,6 +2538,13 @@ public class BigInteger extends Number implements Comparable<BigInteger>
if (n < 0)
throw new ArithmeticException();
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ mpz.setBit(n, true, result.mpz);
+ return result;
+ }
+
return or(ONE.shiftLeft(n));
}
@@ -2176,6 +2553,9 @@ public class BigInteger extends Number implements Comparable<BigInteger>
if (n < 0)
throw new ArithmeticException();
+ if (USING_NATIVE)
+ return mpz.testBit(n) != 0;
+
return !and(ONE.shiftLeft(n)).isZero();
}
@@ -2184,11 +2564,21 @@ public class BigInteger extends Number implements Comparable<BigInteger>
if (n < 0)
throw new ArithmeticException();
+ if (USING_NATIVE)
+ {
+ BigInteger result = new BigInteger();
+ mpz.flipBit(n, result.mpz);
+ return result;
+ }
+
return xor(ONE.shiftLeft(n));
}
public int getLowestSetBit()
{
+ if (USING_NATIVE)
+ return mpz.compare(ZERO.mpz) == 0 ? -1 : mpz.lowestSetBit();
+
if (isZero())
return -1;
@@ -2225,6 +2615,9 @@ public class BigInteger extends Number implements Comparable<BigInteger>
* If argument is negative, count zero bits instead. */
public int bitCount()
{
+ if (USING_NATIVE)
+ return mpz.bitCount();
+
int i, x_len;
int[] x_words = words;
if (x_words == null)
@@ -2243,19 +2636,30 @@ public class BigInteger extends Number implements Comparable<BigInteger>
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
- s.defaultReadObject();
- if (magnitude.length == 0 || signum == 0)
+ if (USING_NATIVE)
{
- this.ival = 0;
- this.words = null;
+ mpz = new GMP();
+ s.defaultReadObject();
+ if (signum != 0)
+ mpz.fromByteArray(magnitude);
+ // else it's zero and we need to do nothing
}
else
{
- words = byteArrayToIntArray(magnitude, signum < 0 ? -1 : 0);
- BigInteger result = make(words, words.length);
- this.ival = result.ival;
- this.words = result.words;
- }
+ s.defaultReadObject();
+ if (magnitude.length == 0 || signum == 0)
+ {
+ this.ival = 0;
+ this.words = null;
+ }
+ else
+ {
+ words = byteArrayToIntArray(magnitude, signum < 0 ? -1 : 0);
+ BigInteger result = make(words, words.length);
+ this.ival = result.ival;
+ this.words = result.words;
+ }
+ }
}
private void writeObject(ObjectOutputStream s)
@@ -2264,5 +2668,9 @@ public class BigInteger extends Number implements Comparable<BigInteger>
signum = signum();
magnitude = signum == 0 ? new byte[0] : toByteArray();
s.defaultWriteObject();
+ magnitude = null; // not needed anymore
}
+
+ // inner class(es) ..........................................................
+
}
diff --git a/libjava/classpath/java/net/Inet4Address.java b/libjava/classpath/java/net/Inet4Address.java
index a8a726ecf80..1a50a472925 100644
--- a/libjava/classpath/java/net/Inet4Address.java
+++ b/libjava/classpath/java/net/Inet4Address.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.ObjectStreamException;
/*
@@ -212,7 +214,7 @@ public final class Inet4Address extends InetAddress
*/
public String getHostAddress()
{
- StringBuffer sb = new StringBuffer(40);
+ CPStringBuilder sb = new CPStringBuilder(40);
int len = addr.length;
int i = 0;
diff --git a/libjava/classpath/java/net/Inet6Address.java b/libjava/classpath/java/net/Inet6Address.java
index f4893eb09f3..9a1c4ea96da 100644
--- a/libjava/classpath/java/net/Inet6Address.java
+++ b/libjava/classpath/java/net/Inet6Address.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import java.util.Arrays;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -317,7 +319,7 @@ public final class Inet6Address extends InetAddress
*/
public String getHostAddress()
{
- StringBuffer sbuf = new StringBuffer(40);
+ CPStringBuilder sbuf = new CPStringBuilder(40);
for (int i = 0; i < 16; i += 2)
{
diff --git a/libjava/classpath/java/net/NetworkInterface.java b/libjava/classpath/java/net/NetworkInterface.java
index a3a6058afa1..5ec64ff16ce 100644
--- a/libjava/classpath/java/net/NetworkInterface.java
+++ b/libjava/classpath/java/net/NetworkInterface.java
@@ -1,5 +1,5 @@
/* NetworkInterface.java --
- Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,6 +40,8 @@ package java.net;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
+
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
@@ -247,10 +249,10 @@ public final class NetworkInterface
public String toString()
{
// FIXME: check if this is correct
- StringBuffer result;
+ CPStringBuilder result;
String separator = SystemProperties.getProperty("line.separator");
- result = new StringBuffer();
+ result = new CPStringBuilder();
result.append("name: ");
result.append(getDisplayName());
@@ -265,4 +267,50 @@ public final class NetworkInterface
return result.toString();
}
+
+ /**
+ * Determines whether this interface is ready to transfer data.
+ *
+ * @return whether the interface is up
+ */
+ public boolean isUp()
+ throws SocketException
+ {
+ return VMNetworkInterface.isUp(netif.name);
+ }
+
+ /**
+ * Determines whether this interface does point to point
+ * transmission.
+ *
+ * @return whether the interface does point to point transmission
+ */
+ public boolean isPointToPoint()
+ throws SocketException
+ {
+ return VMNetworkInterface.isPointToPoint(netif.name);
+ }
+
+ /**
+ * Determines whether this interface is the loopback interface.
+ *
+ * @return whether the interface is the loopback interface
+ */
+ public boolean isLoopback()
+ throws SocketException
+ {
+ return VMNetworkInterface.isLoopback(netif.name);
+ }
+
+ /**
+ * Determines whether this interface supports multicast transmission.
+ *
+ * @return whether the interface supports multicast transmission.
+ */
+ public boolean supportsMulticast()
+ throws SocketException
+ {
+ return VMNetworkInterface.supportsMulticast(netif.name);
+ }
+
}
diff --git a/libjava/classpath/java/net/SocketPermission.java b/libjava/classpath/java/net/SocketPermission.java
index 64885438aed..a5a848eee7a 100644
--- a/libjava/classpath/java/net/SocketPermission.java
+++ b/libjava/classpath/java/net/SocketPermission.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -431,7 +433,7 @@ public final class SocketPermission extends Permission implements Serializable
*/
public String getActions()
{
- StringBuffer sb = new StringBuffer("");
+ CPStringBuilder sb = new CPStringBuilder("");
for (int i = 0; i < ACTIONS.length; i++)
{
diff --git a/libjava/classpath/java/net/URI.java b/libjava/classpath/java/net/URI.java
index 85e0e04f236..933e4f451f0 100644
--- a/libjava/classpath/java/net/URI.java
+++ b/libjava/classpath/java/net/URI.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -483,7 +485,7 @@ public final class URI
*/
private static String quote(String str, String legalCharacters)
{
- StringBuilder sb = new StringBuilder(str.length());
+ CPStringBuilder sb = new CPStringBuilder(str.length());
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
@@ -778,8 +780,8 @@ public final class URI
This follows the algorithm in section 5.2.4. of RFC3986,
but doesn't modify the input buffer.
*/
- StringBuilder input = new StringBuilder(relativePath);
- StringBuilder output = new StringBuilder();
+ CPStringBuilder input = new CPStringBuilder(relativePath);
+ CPStringBuilder output = new CPStringBuilder();
int start = 0;
while (start < input.length())
{
@@ -853,7 +855,7 @@ public final class URI
*
* @param buffer the buffer containing the path.
*/
- private void removeLastSegment(StringBuilder buffer)
+ private void removeLastSegment(CPStringBuilder buffer)
{
int lastSlash = buffer.lastIndexOf("/");
if (lastSlash == -1)
@@ -899,7 +901,7 @@ public final class URI
path = "";
if (! (path.startsWith("/")))
{
- StringBuilder basepath = new StringBuilder(this.path);
+ CPStringBuilder basepath = new CPStringBuilder(this.path);
int i = this.path.lastIndexOf('/');
if (i >= 0)
@@ -1388,8 +1390,8 @@ public final class URI
{
String strRep = toString();
boolean inNonAsciiBlock = false;
- StringBuilder buffer = new StringBuilder();
- StringBuilder encBuffer = null;
+ CPStringBuilder buffer = new CPStringBuilder();
+ CPStringBuilder encBuffer = null;
for (int i = 0; i < strRep.length(); i++)
{
char c = strRep.charAt(i);
@@ -1406,7 +1408,7 @@ public final class URI
{
if (!inNonAsciiBlock)
{
- encBuffer = new StringBuilder();
+ encBuffer = new CPStringBuilder();
inNonAsciiBlock = true;
}
encBuffer.append(c);
@@ -1428,7 +1430,7 @@ public final class URI
{
try
{
- StringBuilder sb = new StringBuilder();
+ CPStringBuilder sb = new CPStringBuilder();
// this is far from optimal, but it works
byte[] utf8 = str.getBytes("utf-8");
for (int j = 0; j < utf8.length; j++)
diff --git a/libjava/classpath/java/net/URLClassLoader.java b/libjava/classpath/java/net/URLClassLoader.java
index e1db2a18e55..52d297a3c17 100644
--- a/libjava/classpath/java/net/URLClassLoader.java
+++ b/libjava/classpath/java/net/URLClassLoader.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.net.loader.FileURLLoader;
import gnu.java.net.loader.JarURLLoader;
import gnu.java.net.loader.RemoteURLLoader;
@@ -452,7 +454,7 @@ public class URLClassLoader extends SecureClassLoader
{
// Compute the name of the package as it may appear in the
// Manifest.
- StringBuilder xform = new StringBuilder(name);
+ CPStringBuilder xform = new CPStringBuilder(name);
for (int i = xform.length () - 1; i >= 0; --i)
if (xform.charAt(i) == '.')
xform.setCharAt(i, '/');
@@ -641,7 +643,7 @@ public class URLClassLoader extends SecureClassLoader
{
if (thisString == null)
{
- StringBuilder sb = new StringBuilder();
+ CPStringBuilder sb = new CPStringBuilder();
sb.append(this.getClass().getName());
sb.append("{urls=[" );
URL[] thisURLs = getURLs();
diff --git a/libjava/classpath/java/net/URLDecoder.java b/libjava/classpath/java/net/URLDecoder.java
index ca40c386a52..fb7ab591696 100644
--- a/libjava/classpath/java/net/URLDecoder.java
+++ b/libjava/classpath/java/net/URLDecoder.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.UnsupportedEncodingException;
@@ -127,7 +129,7 @@ public class URLDecoder
int start = 0;
byte[] bytes = null;
int length = str.length();
- StringBuffer result = new StringBuffer(length);
+ CPStringBuilder result = new CPStringBuilder(length);
while ((i = str.indexOf('%', start)) >= 0)
{
// Add all non-encoded characters to the result buffer
diff --git a/libjava/classpath/java/net/URLEncoder.java b/libjava/classpath/java/net/URLEncoder.java
index 2f11c501b17..89d9a0bd04c 100644
--- a/libjava/classpath/java/net/URLEncoder.java
+++ b/libjava/classpath/java/net/URLEncoder.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.UnsupportedEncodingException;
@@ -113,7 +115,7 @@ public class URLEncoder
int start = 0;
int i = 0;
- StringBuilder result = new StringBuilder(length);
+ CPStringBuilder result = new CPStringBuilder(length);
while (true)
{
while (i < length && isSafe(s.charAt(i)))
diff --git a/libjava/classpath/java/net/URLStreamHandler.java b/libjava/classpath/java/net/URLStreamHandler.java
index 9a5d73ad0d0..4748191e07b 100644
--- a/libjava/classpath/java/net/URLStreamHandler.java
+++ b/libjava/classpath/java/net/URLStreamHandler.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.net;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.File;
import java.io.IOException;
@@ -510,7 +512,7 @@ public abstract class URLStreamHandler
// Guess a reasonable size for the string buffer so we have to resize
// at most once.
int size = protocol.length() + authority.length() + file.length() + 24;
- StringBuffer sb = new StringBuffer(size);
+ CPStringBuilder sb = new CPStringBuilder(size);
if (protocol.length() > 0)
{
diff --git a/libjava/classpath/java/nio/Buffer.java b/libjava/classpath/java/nio/Buffer.java
index c2569eea975..fce60c88ce2 100644
--- a/libjava/classpath/java/nio/Buffer.java
+++ b/libjava/classpath/java/nio/Buffer.java
@@ -45,19 +45,21 @@ import gnu.classpath.Pointer;
*/
public abstract class Buffer
{
- int cap = 0;
- int limit = 0;
- int pos = 0;
- int mark = -1;
- Pointer address;
+ private final int cap;
+ int limit;
+ int pos;
+ int mark;
+ final Pointer address;
/**
* Creates a new Buffer.
*
* Should be package private.
*/
- Buffer (int capacity, int limit, int position, int mark)
+ Buffer (int capacity, int limit, int position, int mark, Pointer address)
{
+ this.address = address;
+
if (capacity < 0)
throw new IllegalArgumentException ();
@@ -72,6 +74,10 @@ public abstract class Buffer
this.mark = mark;
}
+ else
+ {
+ this.mark = -1;
+ }
}
/**
diff --git a/libjava/classpath/java/nio/ByteBuffer.java b/libjava/classpath/java/nio/ByteBuffer.java
index 78ad4471836..94aae4bf021 100644
--- a/libjava/classpath/java/nio/ByteBuffer.java
+++ b/libjava/classpath/java/nio/ByteBuffer.java
@@ -38,6 +38,10 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Change gnu.classpath.Pointer to RawData
+import gnu.gcj.RawData;
+import gnu.classpath.Pointer;
+
/**
* @since 1.4
*/
@@ -45,13 +49,15 @@ public abstract class ByteBuffer extends Buffer
implements Comparable<ByteBuffer>
{
ByteOrder endian = ByteOrder.BIG_ENDIAN;
+ final byte[] backing_buffer;
+ final int array_offset;
- int array_offset;
- byte[] backing_buffer;
-
- ByteBuffer (int capacity, int limit, int position, int mark)
+ ByteBuffer (int capacity, int limit, int position, int mark,
+ RawData address, byte[] backing_buffer, int array_offset)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, address);
+ this.backing_buffer = backing_buffer;
+ this.array_offset = array_offset;
}
/**
diff --git a/libjava/classpath/java/nio/ByteBufferImpl.java b/libjava/classpath/java/nio/ByteBufferImpl.java
index aa51a65bdd5..6a1ac4681da 100644
--- a/libjava/classpath/java/nio/ByteBufferImpl.java
+++ b/libjava/classpath/java/nio/ByteBufferImpl.java
@@ -43,13 +43,12 @@ package java.nio;
*/
final class ByteBufferImpl extends ByteBuffer
{
- private boolean readOnly;
+ private final boolean readOnly;
- ByteBufferImpl (byte[] buffer, int offset, int capacity, int limit, int position, int mark, boolean readOnly)
+ ByteBufferImpl (byte[] buffer, int offset, int capacity, int limit,
+ int position, int mark, boolean readOnly)
{
- super (capacity, limit, position, mark);
- this.backing_buffer = buffer;
- this.array_offset = offset;
+ super (capacity, limit, position, mark, null, buffer, offset);
this.readOnly = readOnly;
}
@@ -90,17 +89,20 @@ final class ByteBufferImpl extends ByteBuffer
public ByteBuffer slice ()
{
- return new ByteBufferImpl (backing_buffer, array_offset + position (), remaining (), remaining (), 0, -1, isReadOnly ());
+ return new ByteBufferImpl (backing_buffer, array_offset + position (),
+ remaining (), remaining (), 0, -1, isReadOnly ());
}
public ByteBuffer duplicate ()
{
- return new ByteBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, isReadOnly ());
+ return new ByteBufferImpl (backing_buffer, array_offset, capacity (),
+ limit (), position (), mark, isReadOnly ());
}
public ByteBuffer asReadOnlyBuffer ()
{
- return new ByteBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, true);
+ return new ByteBufferImpl (backing_buffer, array_offset, capacity (),
+ limit (), position (), mark, true);
}
void shiftDown (int dst_offset, int src_offset, int count)
diff --git a/libjava/classpath/java/nio/CharBuffer.java b/libjava/classpath/java/nio/CharBuffer.java
index 2feada4c817..969b5bb3df3 100644
--- a/libjava/classpath/java/nio/CharBuffer.java
+++ b/libjava/classpath/java/nio/CharBuffer.java
@@ -38,6 +38,9 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Use RawData instead of gnu.classpath.Pointer
+import gnu.gcj.RawData;
+
import java.io.IOException;
/**
@@ -46,13 +49,15 @@ import java.io.IOException;
public abstract class CharBuffer extends Buffer
implements Comparable<CharBuffer>, CharSequence, Readable, Appendable
{
- int array_offset;
- char[] backing_buffer;
+ final int array_offset;
+ final char[] backing_buffer;
- CharBuffer (int capacity, int limit, int position, int mark)
+ CharBuffer (int capacity, int limit, int position, int mark,
+ RawData address, char[] backing_buffer, int array_offset)
{
- super (capacity, limit, position, mark);
- array_offset = 0;
+ super (capacity, limit, position, mark, address);
+ this.backing_buffer = backing_buffer;
+ this.array_offset = array_offset;
}
/**
@@ -78,7 +83,8 @@ public abstract class CharBuffer extends Buffer
*/
public static final CharBuffer wrap(char[] array, int offset, int length)
{
- return new CharBufferImpl(array, 0, array.length, offset + length, offset, -1, false);
+ return new CharBufferImpl(array, 0, array.length, offset + length, offset,
+ -1, false);
}
/**
diff --git a/libjava/classpath/java/nio/CharBufferImpl.java b/libjava/classpath/java/nio/CharBufferImpl.java
index e6097cb7516..d35ca5962f1 100644
--- a/libjava/classpath/java/nio/CharBufferImpl.java
+++ b/libjava/classpath/java/nio/CharBufferImpl.java
@@ -43,7 +43,7 @@ package java.nio;
*/
final class CharBufferImpl extends CharBuffer
{
- private boolean readOnly;
+ private final boolean readOnly;
CharBufferImpl (int capacity)
{
@@ -52,18 +52,14 @@ final class CharBufferImpl extends CharBuffer
CharBufferImpl (char[] buffer, int offset, int capacity, int limit, int position, int mark, boolean readOnly)
{
- super (capacity, limit, position, mark);
- this.backing_buffer = buffer;
- this.array_offset = offset;
+ super (capacity, limit, position, mark, null, buffer, offset);
this.readOnly = readOnly;
}
public CharBufferImpl (CharBufferImpl copy)
{
- super (copy.capacity (), copy.limit (), copy.position (), 0);
- backing_buffer = copy.backing_buffer;
- array_offset = copy.array_offset;
- readOnly = copy.isReadOnly ();
+ super (copy.capacity (), copy.limit (), copy.position (), 0, null, copy.backing_buffer, copy.array_offset);
+ this.readOnly = copy.isReadOnly ();
}
public boolean isReadOnly ()
diff --git a/libjava/classpath/java/nio/CharSequenceBuffer.java b/libjava/classpath/java/nio/CharSequenceBuffer.java
index 26aad1c38ac..3003670d83c 100644
--- a/libjava/classpath/java/nio/CharSequenceBuffer.java
+++ b/libjava/classpath/java/nio/CharSequenceBuffer.java
@@ -48,7 +48,7 @@ final class CharSequenceBuffer
/**
* The wrapped char sequence.
*/
- private CharSequence charSequence;
+ private final CharSequence charSequence;
/**
* Creates a new CharSequenceBuffer.
@@ -63,9 +63,8 @@ final class CharSequenceBuffer
CharSequenceBuffer(CharSequence charSeq, int capacity, int limit,
int position, int mark, int offs)
{
- super(capacity, limit, position, mark);
- charSequence = charSeq;
- array_offset = offs;
+ super(capacity, limit, position, mark, null, null, offs);
+ this.charSequence = charSeq;
}
/**
@@ -105,7 +104,7 @@ final class CharSequenceBuffer
*/
public CharBuffer duplicate()
{
- return new CharSequenceBuffer(charSequence, cap, limit, pos, mark, 0);
+ return new CharSequenceBuffer(charSequence, capacity(), limit, pos, mark, 0);
}
/**
diff --git a/libjava/classpath/java/nio/CharViewBufferImpl.java b/libjava/classpath/java/nio/CharViewBufferImpl.java
index 33bbac8b000..98a27a6e601 100644
--- a/libjava/classpath/java/nio/CharViewBufferImpl.java
+++ b/libjava/classpath/java/nio/CharViewBufferImpl.java
@@ -41,33 +41,33 @@ package java.nio;
class CharViewBufferImpl extends CharBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
- private int offset;
- private ByteBuffer bb;
- private boolean readOnly;
- private ByteOrder endian;
+ private final int offset;
+ private final ByteBuffer bb;
+ private final boolean readOnly;
+ private final ByteOrder endian;
CharViewBufferImpl (ByteBuffer bb, int capacity)
{
- super (capacity, capacity, 0, -1);
+ super (capacity, capacity, 0, -1, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, bb.position()) : null,
+ null, 0);
this.bb = bb;
this.offset = bb.position();
this.readOnly = bb.isReadOnly();
this.endian = bb.order();
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
public CharViewBufferImpl (ByteBuffer bb, int offset, int capacity,
int limit, int position, int mark,
boolean readOnly, ByteOrder endian)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, offset) : null,
+ null, 0);
this.bb = bb;
this.offset = offset;
this.readOnly = readOnly;
this.endian = endian;
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
/**
diff --git a/libjava/classpath/java/nio/DirectByteBufferImpl.java b/libjava/classpath/java/nio/DirectByteBufferImpl.java
index 8c907f597f0..60df3611ac9 100644
--- a/libjava/classpath/java/nio/DirectByteBufferImpl.java
+++ b/libjava/classpath/java/nio/DirectByteBufferImpl.java
@@ -104,18 +104,16 @@ abstract class DirectByteBufferImpl extends ByteBuffer
DirectByteBufferImpl(int capacity)
{
- super(capacity, capacity, 0, -1);
+ super(capacity, capacity, 0, -1, VMDirectByteBuffer.allocate(capacity), null, 0);
this.owner = this;
- this.address = VMDirectByteBuffer.allocate(capacity);
}
DirectByteBufferImpl(Object owner, Pointer address,
int capacity, int limit,
int position)
{
- super(capacity, limit, position, -1);
+ super(capacity, limit, position, -1, address, null, 0);
this.owner = owner;
- this.address = address;
}
/**
diff --git a/libjava/classpath/java/nio/DoubleBuffer.java b/libjava/classpath/java/nio/DoubleBuffer.java
index be7861cbd5e..1a51f1889be 100644
--- a/libjava/classpath/java/nio/DoubleBuffer.java
+++ b/libjava/classpath/java/nio/DoubleBuffer.java
@@ -38,19 +38,24 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Change gnu.classpath.Pointer to RawData
+import gnu.gcj.RawData;
+
/**
* @since 1.4
*/
public abstract class DoubleBuffer extends Buffer
implements Comparable<DoubleBuffer>
{
- int array_offset;
- double[] backing_buffer;
+ final int array_offset;
+ final double[] backing_buffer;
- DoubleBuffer (int capacity, int limit, int position, int mark)
+ DoubleBuffer (int capacity, int limit, int position, int mark,
+ RawData address, double[] backing_buffer, int array_offset)
{
- super (capacity, limit, position, mark);
- array_offset = 0;
+ super (capacity, limit, position, mark, address);
+ this.backing_buffer = backing_buffer;
+ this.array_offset = array_offset;
}
/**
diff --git a/libjava/classpath/java/nio/DoubleBufferImpl.java b/libjava/classpath/java/nio/DoubleBufferImpl.java
index 98e8e974fff..bc292df646d 100644
--- a/libjava/classpath/java/nio/DoubleBufferImpl.java
+++ b/libjava/classpath/java/nio/DoubleBufferImpl.java
@@ -43,18 +43,17 @@ package java.nio;
*/
final class DoubleBufferImpl extends DoubleBuffer
{
- private boolean readOnly;
+ private final boolean readOnly;
DoubleBufferImpl (int capacity)
{
this (new double [capacity], 0, capacity, capacity, 0, -1, false);
}
- DoubleBufferImpl (double[] buffer, int offset, int capacity, int limit, int position, int mark, boolean readOnly)
+ DoubleBufferImpl (double[] buffer, int offset, int capacity, int limit,
+ int position, int mark, boolean readOnly)
{
- super (capacity, limit, position, mark);
- this.backing_buffer = buffer;
- this.array_offset = offset;
+ super (capacity, limit, position, mark, null, buffer, offset);
this.readOnly = readOnly;
}
@@ -65,17 +64,20 @@ final class DoubleBufferImpl extends DoubleBuffer
public DoubleBuffer slice ()
{
- return new DoubleBufferImpl (backing_buffer, array_offset + position (), remaining (), remaining (), 0, -1, isReadOnly ());
+ return new DoubleBufferImpl (backing_buffer, array_offset + position (),
+ remaining (), remaining (), 0, -1, isReadOnly ());
}
public DoubleBuffer duplicate ()
{
- return new DoubleBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, isReadOnly ());
+ return new DoubleBufferImpl (backing_buffer, array_offset, capacity (),
+ limit (), position (), mark, isReadOnly ());
}
public DoubleBuffer asReadOnlyBuffer ()
{
- return new DoubleBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, true);
+ return new DoubleBufferImpl (backing_buffer, array_offset, capacity (),
+ limit (), position (), mark, true);
}
public DoubleBuffer compact ()
diff --git a/libjava/classpath/java/nio/DoubleViewBufferImpl.java b/libjava/classpath/java/nio/DoubleViewBufferImpl.java
index d1399154a71..d82fa92c4a7 100644
--- a/libjava/classpath/java/nio/DoubleViewBufferImpl.java
+++ b/libjava/classpath/java/nio/DoubleViewBufferImpl.java
@@ -41,33 +41,31 @@ package java.nio;
final class DoubleViewBufferImpl extends DoubleBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
- private int offset;
- private ByteBuffer bb;
- private boolean readOnly;
- private ByteOrder endian;
+ private final int offset;
+ private final ByteBuffer bb;
+ private final boolean readOnly;
+ private final ByteOrder endian;
DoubleViewBufferImpl (ByteBuffer bb, int capacity)
{
- super (capacity, capacity, 0, -1);
+ super (capacity, capacity, 0, -1, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, bb.position()) : null, null, 0);
this.bb = bb;
this.offset = bb.position();
this.readOnly = bb.isReadOnly();
this.endian = bb.order();
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
public DoubleViewBufferImpl (ByteBuffer bb, int offset, int capacity,
int limit, int position, int mark,
boolean readOnly, ByteOrder endian)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, bb.position()) : null, null, 0);
this.bb = bb;
this.offset = offset;
this.readOnly = readOnly;
this.endian = endian;
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
/**
diff --git a/libjava/classpath/java/nio/FloatBuffer.java b/libjava/classpath/java/nio/FloatBuffer.java
index 62e353a6818..ce40a09e37b 100644
--- a/libjava/classpath/java/nio/FloatBuffer.java
+++ b/libjava/classpath/java/nio/FloatBuffer.java
@@ -38,19 +38,24 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Change gnu.classpath.Pointer to RawData
+import gnu.gcj.RawData;
+
/**
* @since 1.4
*/
public abstract class FloatBuffer extends Buffer
implements Comparable<FloatBuffer>
{
- int array_offset;
- float[] backing_buffer;
+ final int array_offset;
+ final float[] backing_buffer;
- FloatBuffer (int capacity, int limit, int position, int mark)
+ FloatBuffer (int capacity, int limit, int position, int mark,
+ RawData address, float[] backing_buffer, int array_offset)
{
- super (capacity, limit, position, mark);
- array_offset = 0;
+ super (capacity, limit, position, mark, address);
+ this.backing_buffer = backing_buffer;
+ this.array_offset = array_offset;
}
/**
diff --git a/libjava/classpath/java/nio/FloatBufferImpl.java b/libjava/classpath/java/nio/FloatBufferImpl.java
index f1182ba38f3..5d0e7ca8590 100644
--- a/libjava/classpath/java/nio/FloatBufferImpl.java
+++ b/libjava/classpath/java/nio/FloatBufferImpl.java
@@ -43,18 +43,17 @@ package java.nio;
*/
final class FloatBufferImpl extends FloatBuffer
{
- private boolean readOnly;
+ private final boolean readOnly;
FloatBufferImpl (int capacity)
{
this (new float [capacity], 0, capacity, capacity, 0, -1, false);
}
- FloatBufferImpl (float[] buffer, int offset, int capacity, int limit, int position, int mark, boolean readOnly)
+ FloatBufferImpl (float[] buffer, int offset, int capacity, int limit,
+ int position, int mark, boolean readOnly)
{
- super (capacity, limit, position, mark);
- this.backing_buffer = buffer;
- this.array_offset = offset;
+ super (capacity, limit, position, mark, null, buffer, offset);
this.readOnly = readOnly;
}
diff --git a/libjava/classpath/java/nio/FloatViewBufferImpl.java b/libjava/classpath/java/nio/FloatViewBufferImpl.java
index 8bb342d103d..9f10d824fe0 100644
--- a/libjava/classpath/java/nio/FloatViewBufferImpl.java
+++ b/libjava/classpath/java/nio/FloatViewBufferImpl.java
@@ -41,33 +41,31 @@ package java.nio;
final class FloatViewBufferImpl extends FloatBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
- private int offset;
- private ByteBuffer bb;
- private boolean readOnly;
- private ByteOrder endian;
+ private final int offset;
+ private final ByteBuffer bb;
+ private final boolean readOnly;
+ private final ByteOrder endian;
FloatViewBufferImpl (ByteBuffer bb, int capacity)
{
- super (capacity, capacity, 0, -1);
+ super (capacity, capacity, 0, -1, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, bb.position()):null, null, 0);
this.bb = bb;
this.offset = bb.position();
this.readOnly = bb.isReadOnly();
this.endian = bb.order();
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
public FloatViewBufferImpl (ByteBuffer bb, int offset, int capacity,
int limit, int position, int mark,
boolean readOnly, ByteOrder endian)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, offset):null, null, 0);
this.bb = bb;
this.offset = offset;
this.readOnly = readOnly;
this.endian = endian;
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
/**
diff --git a/libjava/classpath/java/nio/IntBuffer.java b/libjava/classpath/java/nio/IntBuffer.java
index d6fcb51ddf0..9234c33ef6d 100644
--- a/libjava/classpath/java/nio/IntBuffer.java
+++ b/libjava/classpath/java/nio/IntBuffer.java
@@ -38,19 +38,24 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Change gnu.classpath.Pointer to RawData
+import gnu.gcj.RawData;
+
/**
* @since 1.4
*/
public abstract class IntBuffer extends Buffer
implements Comparable<IntBuffer>
{
- int array_offset;
- int[] backing_buffer;
+ final int array_offset;
+ final int[] backing_buffer;
- IntBuffer (int capacity, int limit, int position, int mark)
+ IntBuffer (int capacity, int limit, int position, int mark, RawData address,
+ int[] backing_buffer, int array_offset)
{
- super (capacity, limit, position, mark);
- array_offset = 0;
+ super (capacity, limit, position, mark, address);
+ this.backing_buffer = backing_buffer;
+ this.array_offset = array_offset;
}
/**
@@ -70,7 +75,8 @@ public abstract class IntBuffer extends Buffer
*/
public static final IntBuffer wrap (int[] array, int offset, int length)
{
- return new IntBufferImpl (array, 0, array.length, offset + length, offset, -1, false);
+ return new IntBufferImpl (array, 0, array.length, offset + length, offset,
+ -1, false);
}
/**
diff --git a/libjava/classpath/java/nio/IntBufferImpl.java b/libjava/classpath/java/nio/IntBufferImpl.java
index 2bd1842440e..c332715fbda 100644
--- a/libjava/classpath/java/nio/IntBufferImpl.java
+++ b/libjava/classpath/java/nio/IntBufferImpl.java
@@ -43,7 +43,7 @@ package java.nio;
*/
final class IntBufferImpl extends IntBuffer
{
- private boolean readOnly;
+ private final boolean readOnly;
IntBufferImpl (int capacity)
{
@@ -52,9 +52,7 @@ final class IntBufferImpl extends IntBuffer
IntBufferImpl (int[] buffer, int offset, int capacity, int limit, int position, int mark, boolean readOnly)
{
- super (capacity, limit, position, mark);
- this.backing_buffer = buffer;
- this.array_offset = offset;
+ super (capacity, limit, position, mark, null, buffer, offset);
this.readOnly = readOnly;
}
diff --git a/libjava/classpath/java/nio/IntViewBufferImpl.java b/libjava/classpath/java/nio/IntViewBufferImpl.java
index cd8307f3ebd..9af5d58a4dc 100644
--- a/libjava/classpath/java/nio/IntViewBufferImpl.java
+++ b/libjava/classpath/java/nio/IntViewBufferImpl.java
@@ -41,33 +41,31 @@ package java.nio;
final class IntViewBufferImpl extends IntBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
- private int offset;
- private ByteBuffer bb;
- private boolean readOnly;
- private ByteOrder endian;
+ private final int offset;
+ private final ByteBuffer bb;
+ private final boolean readOnly;
+ private final ByteOrder endian;
IntViewBufferImpl (ByteBuffer bb, int capacity)
{
- super (capacity, capacity, 0, -1);
+ super (capacity, capacity, 0, -1, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, bb.position()):null, null, 0);
this.bb = bb;
this.offset = bb.position();
this.readOnly = bb.isReadOnly();
this.endian = bb.order();
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
public IntViewBufferImpl (ByteBuffer bb, int offset, int capacity,
int limit, int position, int mark,
boolean readOnly, ByteOrder endian)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, offset):null, null, 0);
this.bb = bb;
this.offset = offset;
this.readOnly = readOnly;
this.endian = endian;
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
/**
diff --git a/libjava/classpath/java/nio/LongBuffer.java b/libjava/classpath/java/nio/LongBuffer.java
index 9c3bfa62741..1195cc88ce2 100644
--- a/libjava/classpath/java/nio/LongBuffer.java
+++ b/libjava/classpath/java/nio/LongBuffer.java
@@ -38,19 +38,24 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Change gnu.classpath.Pointer to RawData
+import gnu.gcj.RawData;
+
/**
* @since 1.4
*/
public abstract class LongBuffer extends Buffer
implements Comparable<LongBuffer>
{
- int array_offset;
- long[] backing_buffer;
+ final int array_offset;
+ final long[] backing_buffer;
- LongBuffer (int capacity, int limit, int position, int mark)
+ LongBuffer (int capacity, int limit, int position, int mark,
+ RawData address, long[] backing_buffer, int array_offset)
{
- super (capacity, limit, position, mark);
- array_offset = 0;
+ super (capacity, limit, position, mark, address);
+ this.backing_buffer = backing_buffer;
+ this.array_offset = array_offset;
}
/**
diff --git a/libjava/classpath/java/nio/LongBufferImpl.java b/libjava/classpath/java/nio/LongBufferImpl.java
index c04c41775a9..4cf922b149d 100644
--- a/libjava/classpath/java/nio/LongBufferImpl.java
+++ b/libjava/classpath/java/nio/LongBufferImpl.java
@@ -43,18 +43,17 @@ package java.nio;
*/
final class LongBufferImpl extends LongBuffer
{
- private boolean readOnly;
+ private final boolean readOnly;
LongBufferImpl (int capacity)
{
this (new long [capacity], 0, capacity, capacity, 0, -1, false);
}
- LongBufferImpl (long[] buffer, int offset, int capacity, int limit, int position, int mark, boolean readOnly)
+ LongBufferImpl (long[] buffer, int offset, int capacity, int limit,
+ int position, int mark, boolean readOnly)
{
- super (capacity, limit, position, mark);
- this.backing_buffer = buffer;
- this.array_offset = offset;
+ super (capacity, limit, position, mark, null, buffer, offset);
this.readOnly = readOnly;
}
@@ -65,17 +64,20 @@ final class LongBufferImpl extends LongBuffer
public LongBuffer slice ()
{
- return new LongBufferImpl (backing_buffer, array_offset + position (), remaining (), remaining (), 0, -1, isReadOnly ());
+ return new LongBufferImpl (backing_buffer, array_offset + position (),
+ remaining (), remaining (), 0, -1, isReadOnly ());
}
public LongBuffer duplicate ()
{
- return new LongBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, isReadOnly ());
+ return new LongBufferImpl (backing_buffer, array_offset, capacity (), limit (),
+ position (), mark, isReadOnly ());
}
public LongBuffer asReadOnlyBuffer ()
{
- return new LongBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, true);
+ return new LongBufferImpl (backing_buffer, array_offset, capacity (), limit (),
+ position (), mark, true);
}
public LongBuffer compact ()
diff --git a/libjava/classpath/java/nio/LongViewBufferImpl.java b/libjava/classpath/java/nio/LongViewBufferImpl.java
index eefbcbdc8dd..b775a99462f 100644
--- a/libjava/classpath/java/nio/LongViewBufferImpl.java
+++ b/libjava/classpath/java/nio/LongViewBufferImpl.java
@@ -41,33 +41,31 @@ package java.nio;
final class LongViewBufferImpl extends LongBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
- private int offset;
- private ByteBuffer bb;
- private boolean readOnly;
- private ByteOrder endian;
+ private final int offset;
+ private final ByteBuffer bb;
+ private final boolean readOnly;
+ private final ByteOrder endian;
LongViewBufferImpl (ByteBuffer bb, int capacity)
{
- super (capacity, capacity, 0, -1);
+ super (capacity, capacity, 0, -1, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, bb.position()):null, null, 0);
this.bb = bb;
this.offset = bb.position();
this.readOnly = bb.isReadOnly();
this.endian = bb.order();
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
public LongViewBufferImpl (ByteBuffer bb, int offset, int capacity,
int limit, int position, int mark,
boolean readOnly, ByteOrder endian)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, offset):null, null, 0);
this.bb = bb;
this.offset = offset;
this.readOnly = readOnly;
this.endian = endian;
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
/**
diff --git a/libjava/classpath/java/nio/MappedByteBuffer.java b/libjava/classpath/java/nio/MappedByteBuffer.java
index 25b0993079a..1f82f823f5a 100644
--- a/libjava/classpath/java/nio/MappedByteBuffer.java
+++ b/libjava/classpath/java/nio/MappedByteBuffer.java
@@ -38,15 +38,19 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Use RawData instead of gnu.classpath.Pointer
+import gnu.gcj.RawData;
+
/**
* @author Michael Koch (konqueror@gmx.de)
* @since 1.4
*/
public abstract class MappedByteBuffer extends ByteBuffer
{
- MappedByteBuffer (int capacity, int limit, int position, int mark)
+ MappedByteBuffer (int capacity, int limit, int position, int mark,
+ RawData address)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, address, null, 0);
}
void forceImpl()
diff --git a/libjava/classpath/java/nio/MappedByteBufferImpl.java b/libjava/classpath/java/nio/MappedByteBufferImpl.java
index a53040f576c..f11d1e72eb2 100644
--- a/libjava/classpath/java/nio/MappedByteBufferImpl.java
+++ b/libjava/classpath/java/nio/MappedByteBufferImpl.java
@@ -44,7 +44,7 @@ import java.io.IOException;
final class MappedByteBufferImpl extends MappedByteBuffer
{
- boolean readOnly;
+ private final boolean readOnly;
/** Posix uses this for the pointer returned by mmap;
* Win32 uses it for the pointer returned by MapViewOfFile. */
@@ -56,8 +56,7 @@ final class MappedByteBufferImpl extends MappedByteBuffer
public MappedByteBufferImpl(Pointer address, int size, boolean readOnly)
throws IOException
{
- super(size, size, 0, -1);
- this.address = address;
+ super(size, size, 0, -1, address);
this.readOnly = readOnly;
}
diff --git a/libjava/classpath/java/nio/ShortBuffer.java b/libjava/classpath/java/nio/ShortBuffer.java
index 33e458a4b1e..f15c0635577 100644
--- a/libjava/classpath/java/nio/ShortBuffer.java
+++ b/libjava/classpath/java/nio/ShortBuffer.java
@@ -38,19 +38,25 @@ exception statement from your version. */
package java.nio;
+// GCJ LOCAL: Use RawData instead of gnu.classpath.Pointer
+import gnu.gcj.RawData;
+
/**
* @since 1.4
*/
public abstract class ShortBuffer extends Buffer
implements Comparable<ShortBuffer>
{
- int array_offset;
- short[] backing_buffer;
+ final int array_offset;
+ final short[] backing_buffer;
- ShortBuffer (int capacity, int limit, int position, int mark)
+ ShortBuffer (int capacity, int limit, int position,
+ int mark, RawData address, short[] backing_buffer,
+ int array_offset)
{
- super (capacity, limit, position, mark);
- array_offset = 0;
+ super (capacity, limit, position, mark, address);
+ this.backing_buffer = backing_buffer;
+ this.array_offset = array_offset;
}
/**
diff --git a/libjava/classpath/java/nio/ShortBufferImpl.java b/libjava/classpath/java/nio/ShortBufferImpl.java
index 50f65ecbfc0..3a8ff57f822 100644
--- a/libjava/classpath/java/nio/ShortBufferImpl.java
+++ b/libjava/classpath/java/nio/ShortBufferImpl.java
@@ -43,18 +43,17 @@ package java.nio;
*/
final class ShortBufferImpl extends ShortBuffer
{
- private boolean readOnly;
+ private final boolean readOnly;
ShortBufferImpl (int capacity)
{
this (new short [capacity], 0, capacity, capacity, 0, -1, false);
}
- ShortBufferImpl (short[] buffer, int offset, int capacity, int limit, int position, int mark, boolean readOnly)
+ ShortBufferImpl (short[] buffer, int offset, int capacity,
+ int limit, int position, int mark, boolean readOnly)
{
- super (capacity, limit, position, mark);
- this.backing_buffer = buffer;
- this.array_offset = offset;
+ super (capacity, limit, position, mark, null, buffer, offset);
this.readOnly = readOnly;
}
@@ -65,17 +64,20 @@ final class ShortBufferImpl extends ShortBuffer
public ShortBuffer slice ()
{
- return new ShortBufferImpl (backing_buffer, array_offset + position (), remaining (), remaining (), 0, -1, isReadOnly ());
+ return new ShortBufferImpl (backing_buffer, array_offset + position (),
+ remaining (), remaining (), 0, -1, isReadOnly ());
}
public ShortBuffer duplicate ()
{
- return new ShortBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, isReadOnly ());
+ return new ShortBufferImpl (backing_buffer, array_offset, capacity (),
+ limit (), position (), mark, isReadOnly ());
}
public ShortBuffer asReadOnlyBuffer ()
{
- return new ShortBufferImpl (backing_buffer, array_offset, capacity (), limit (), position (), mark, true);
+ return new ShortBufferImpl (backing_buffer, array_offset, capacity (), limit (),
+ position (), mark, true);
}
public ShortBuffer compact ()
diff --git a/libjava/classpath/java/nio/ShortViewBufferImpl.java b/libjava/classpath/java/nio/ShortViewBufferImpl.java
index df7133612d2..3c7c7747802 100644
--- a/libjava/classpath/java/nio/ShortViewBufferImpl.java
+++ b/libjava/classpath/java/nio/ShortViewBufferImpl.java
@@ -41,33 +41,31 @@ package java.nio;
final class ShortViewBufferImpl extends ShortBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
- private int offset;
- private ByteBuffer bb;
- private boolean readOnly;
- private ByteOrder endian;
+ private final int offset;
+ private final ByteBuffer bb;
+ private final boolean readOnly;
+ private final ByteOrder endian;
ShortViewBufferImpl (ByteBuffer bb, int capacity)
{
- super (capacity, capacity, 0, -1);
+ super (capacity, capacity, 0, -1, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, bb.position()):null, null, 0);
this.bb = bb;
this.offset = bb.position();
this.readOnly = bb.isReadOnly();
this.endian = bb.order();
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
public ShortViewBufferImpl (ByteBuffer bb, int offset, int capacity,
int limit, int position, int mark,
boolean readOnly, ByteOrder endian)
{
- super (capacity, limit, position, mark);
+ super (capacity, limit, position, mark, bb.isDirect() ?
+ VMDirectByteBuffer.adjustAddress(bb.address, offset):null, null, 0);
this.bb = bb;
this.offset = offset;
this.readOnly = readOnly;
this.endian = endian;
- if (bb.isDirect())
- this.address = VMDirectByteBuffer.adjustAddress(bb.address, offset);
}
/**
diff --git a/libjava/classpath/java/nio/channels/FileLock.java b/libjava/classpath/java/nio/channels/FileLock.java
index c46695837a7..78210b34d4d 100644
--- a/libjava/classpath/java/nio/channels/FileLock.java
+++ b/libjava/classpath/java/nio/channels/FileLock.java
@@ -37,8 +37,9 @@ exception statement from your version. */
package java.nio.channels;
-import java.io.IOException;
+import gnu.java.lang.CPStringBuilder;
+import java.io.IOException;
/**
* @since 1.4
@@ -132,7 +133,7 @@ public abstract class FileLock
*/
public final String toString()
{
- StringBuffer buf = new StringBuffer(getClass().getName());
+ CPStringBuilder buf = new CPStringBuilder(getClass().getName());
buf.append("[");
buf.append(position);
buf.append(":");
diff --git a/libjava/classpath/java/rmi/activation/Activatable.java b/libjava/classpath/java/rmi/activation/Activatable.java
index 0f201cacf63..eb51100304f 100644
--- a/libjava/classpath/java/rmi/activation/Activatable.java
+++ b/libjava/classpath/java/rmi/activation/Activatable.java
@@ -462,8 +462,8 @@ public abstract class Activatable
* means anonymous port.
* @param serverSocketFactory the server socket factory
*/
- public static Remote export(ActivationID id, Remote obj, int port,
- RMIServerSocketFactory serverSocketFactory)
+ private static Remote export(ActivationID id, Remote obj, int port,
+ RMIServerSocketFactory serverSocketFactory)
throws RemoteException
{
ActivatableServerRef sref = null;
@@ -479,7 +479,7 @@ public abstract class Activatable
*
* @return the object id
*/
- public static ObjID makeId(ActivationID aid)
+ private static ObjID makeId(ActivationID aid)
{
ObjID id = new ObjID(0);
diff --git a/libjava/classpath/java/rmi/dgc/VMID.java b/libjava/classpath/java/rmi/dgc/VMID.java
index dc989c265d8..22b737367df 100644
--- a/libjava/classpath/java/rmi/dgc/VMID.java
+++ b/libjava/classpath/java/rmi/dgc/VMID.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.rmi.dgc;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -168,7 +170,7 @@ public final class VMID implements Serializable
*/
public String toString ()
{
- StringBuffer buf = new StringBuffer ("[VMID: ");
+ CPStringBuilder buf = new CPStringBuilder ("[VMID: ");
for (int i = 0; i < addr.length; i++)
{
diff --git a/libjava/classpath/java/security/AlgorithmParameterGenerator.java b/libjava/classpath/java/security/AlgorithmParameterGenerator.java
index e2a17d4bf9c..da1ea46d214 100644
--- a/libjava/classpath/java/security/AlgorithmParameterGenerator.java
+++ b/libjava/classpath/java/security/AlgorithmParameterGenerator.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
@@ -171,7 +173,7 @@ public class AlgorithmParameterGenerator
Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder()
+ CPStringBuilder sb = new CPStringBuilder()
.append("AlgorithmParameterGenerator for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] could not be created");
diff --git a/libjava/classpath/java/security/AlgorithmParameters.java b/libjava/classpath/java/security/AlgorithmParameters.java
index f5e5063a17d..3de8ad02c05 100644
--- a/libjava/classpath/java/security/AlgorithmParameters.java
+++ b/libjava/classpath/java/security/AlgorithmParameters.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.io.IOException;
@@ -175,7 +177,7 @@ public class AlgorithmParameters
Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("AlgorithmParameters for algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("AlgorithmParameters for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] could not be created");
Throwable cause;
diff --git a/libjava/classpath/java/security/CodeSource.java b/libjava/classpath/java/security/CodeSource.java
index b516170281c..90eb089079d 100644
--- a/libjava/classpath/java/security/CodeSource.java
+++ b/libjava/classpath/java/security/CodeSource.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -259,7 +261,7 @@ public class CodeSource implements Serializable
*/
public String toString()
{
- StringBuffer sb = new StringBuffer("(").append(location);
+ CPStringBuilder sb = new CPStringBuilder("(").append(location);
if (certs == null || certs.isEmpty())
sb.append(" <no certificates>");
else
diff --git a/libjava/classpath/java/security/KeyFactory.java b/libjava/classpath/java/security/KeyFactory.java
index 043dd59a151..f06004bad7e 100644
--- a/libjava/classpath/java/security/KeyFactory.java
+++ b/libjava/classpath/java/security/KeyFactory.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
@@ -165,7 +167,7 @@ public class KeyFactory
public static KeyFactory getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("KeyFactory for algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("KeyFactory for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] could not be created");
Throwable cause;
diff --git a/libjava/classpath/java/security/KeyPairGenerator.java b/libjava/classpath/java/security/KeyPairGenerator.java
index 6974035fd6b..f4ca20611e1 100644
--- a/libjava/classpath/java/security/KeyPairGenerator.java
+++ b/libjava/classpath/java/security/KeyPairGenerator.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
@@ -165,7 +167,7 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi
Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("KeyPairGenerator for algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("KeyPairGenerator for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] ");
Object o;
diff --git a/libjava/classpath/java/security/MessageDigest.java b/libjava/classpath/java/security/MessageDigest.java
index 0f8e934e5e9..d94d96b1aa6 100644
--- a/libjava/classpath/java/security/MessageDigest.java
+++ b/libjava/classpath/java/security/MessageDigest.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.nio.ByteBuffer;
@@ -146,7 +148,7 @@ public abstract class MessageDigest extends MessageDigestSpi
public static MessageDigest getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("MessageDigest for algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("MessageDigest for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] ");
Object o;
@@ -235,7 +237,7 @@ public abstract class MessageDigest extends MessageDigestSpi
* @param input The input byte buffer.
* @since 1.5
*/
- public void update (ByteBuffer input)
+ public final void update (ByteBuffer input)
{
engineUpdate (input);
}
@@ -363,7 +365,7 @@ public abstract class MessageDigest extends MessageDigestSpi
if (digest == null)
return "incomplete";
- StringBuffer buf = new StringBuffer();
+ CPStringBuilder buf = new CPStringBuilder();
int len = digest.length;
for (int i = 0; i < len; ++i)
{
diff --git a/libjava/classpath/java/security/Permission.java b/libjava/classpath/java/security/Permission.java
index 9072d95652e..8f3e2a23646 100644
--- a/libjava/classpath/java/security/Permission.java
+++ b/libjava/classpath/java/security/Permission.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Serializable;
/**
@@ -181,7 +183,7 @@ public abstract class Permission implements Guard, Serializable
*/
public String toString()
{
- StringBuffer string = new StringBuffer();
+ CPStringBuilder string = new CPStringBuilder();
string = string.append('(');
string = string.append(getClass().getName());
diff --git a/libjava/classpath/java/security/PermissionCollection.java b/libjava/classpath/java/security/PermissionCollection.java
index c5849830ad7..ef87cc7e1d5 100644
--- a/libjava/classpath/java/security/PermissionCollection.java
+++ b/libjava/classpath/java/security/PermissionCollection.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Serializable;
import java.util.Enumeration;
@@ -156,7 +158,7 @@ public abstract class PermissionCollection implements Serializable
*/
public String toString()
{
- StringBuffer sb = new StringBuffer(super.toString());
+ CPStringBuilder sb = new CPStringBuilder(super.toString());
sb.append(" (\n");
Enumeration<Permission> e = elements();
diff --git a/libjava/classpath/java/security/ProtectionDomain.java b/libjava/classpath/java/security/ProtectionDomain.java
index 33af8fdb843..b1eb049e3f2 100644
--- a/libjava/classpath/java/security/ProtectionDomain.java
+++ b/libjava/classpath/java/security/ProtectionDomain.java
@@ -39,6 +39,8 @@ package java.security;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
+
/**
* This class represents a group of classes, along with their granted
* permissions. The classes are identified by a {@link CodeSource}. Thus, any
@@ -204,7 +206,7 @@ public class ProtectionDomain
public String toString()
{
String linesep = SystemProperties.getProperty("line.separator");
- StringBuffer sb = new StringBuffer("ProtectionDomain (").append(linesep);
+ CPStringBuilder sb = new CPStringBuilder("ProtectionDomain (").append(linesep);
if (code_source == null)
sb.append("CodeSource:null");
diff --git a/libjava/classpath/java/security/SecureRandom.java b/libjava/classpath/java/security/SecureRandom.java
index 005f4670efc..f965782369c 100644
--- a/libjava/classpath/java/security/SecureRandom.java
+++ b/libjava/classpath/java/security/SecureRandom.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package java.security;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
import gnu.java.security.Engine;
import gnu.java.security.action.GetSecurityPropertyAction;
import gnu.java.security.jce.prng.Sha160RandomSpi;
@@ -262,7 +263,7 @@ public class SecureRandom extends Random
public static SecureRandom getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("SecureRandom for algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("SecureRandom for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] could not be created");
Throwable cause;
diff --git a/libjava/classpath/java/security/Signature.java b/libjava/classpath/java/security/Signature.java
index 1245707f7af..26333b68687 100644
--- a/libjava/classpath/java/security/Signature.java
+++ b/libjava/classpath/java/security/Signature.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
@@ -198,7 +200,7 @@ public abstract class Signature extends SignatureSpi
public static Signature getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("Signature algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("Signature algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] ");
Object o;
diff --git a/libjava/classpath/java/security/cert/CertPath.java b/libjava/classpath/java/security/cert/CertPath.java
index 781eb3e2776..7211647a40e 100644
--- a/libjava/classpath/java/security/cert/CertPath.java
+++ b/libjava/classpath/java/security/cert/CertPath.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.security.cert;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.ByteArrayInputStream;
import java.io.NotSerializableException;
import java.io.ObjectStreamException;
@@ -196,7 +198,7 @@ public abstract class CertPath implements Serializable
List l = getCertificates();
int size = l.size();
int i = 0;
- StringBuffer result = new StringBuffer(type);
+ CPStringBuilder result = new CPStringBuilder(type);
result.append(" Cert Path: length = ").append(size).append(".\n[\n");
while (--size >= 0)
result.append(l.get(i++)).append('\n');
diff --git a/libjava/classpath/java/security/cert/CertPathBuilder.java b/libjava/classpath/java/security/cert/CertPathBuilder.java
index 519ed2b6c52..99f7c975252 100644
--- a/libjava/classpath/java/security/cert/CertPathBuilder.java
+++ b/libjava/classpath/java/security/cert/CertPathBuilder.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security.cert;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
@@ -182,7 +184,7 @@ public class CertPathBuilder
public static CertPathBuilder getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("CertPathBuilder for algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("CertPathBuilder for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] could not be created");
Throwable cause;
diff --git a/libjava/classpath/java/security/cert/CertPathValidator.java b/libjava/classpath/java/security/cert/CertPathValidator.java
index bf7c9746e24..af08b54a84e 100644
--- a/libjava/classpath/java/security/cert/CertPathValidator.java
+++ b/libjava/classpath/java/security/cert/CertPathValidator.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security.cert;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
@@ -196,7 +198,7 @@ public class CertPathValidator {
Provider provider)
throws NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("CertPathValidator for algorithm [")
+ CPStringBuilder sb = new CPStringBuilder("CertPathValidator for algorithm [")
.append(algorithm).append("] from provider[")
.append(provider).append("] could not be created");
Throwable cause;
diff --git a/libjava/classpath/java/security/cert/CertStore.java b/libjava/classpath/java/security/cert/CertStore.java
index a27086562e6..1ebdb50337b 100644
--- a/libjava/classpath/java/security/cert/CertStore.java
+++ b/libjava/classpath/java/security/cert/CertStore.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security.cert;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
@@ -207,7 +209,7 @@ public class CertStore
Provider provider)
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException
{
- StringBuilder sb = new StringBuilder("CertStore of type [")
+ CPStringBuilder sb = new CPStringBuilder("CertStore of type [")
.append(type).append("] from provider[")
.append(provider).append("] could not be created");
Throwable cause;
diff --git a/libjava/classpath/java/security/cert/PKIXBuilderParameters.java b/libjava/classpath/java/security/cert/PKIXBuilderParameters.java
index 5e234cec158..fd5f1f87fd0 100644
--- a/libjava/classpath/java/security/cert/PKIXBuilderParameters.java
+++ b/libjava/classpath/java/security/cert/PKIXBuilderParameters.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security.cert;
+import gnu.java.lang.CPStringBuilder;
+
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -140,7 +142,7 @@ public class PKIXBuilderParameters extends PKIXParameters
public String toString()
{
- StringBuffer buf = new StringBuffer(super.toString());
+ CPStringBuilder buf = new CPStringBuilder(super.toString());
buf.insert(buf.length() - 2, "; Max Path Length=" + maxPathLength);
return buf.toString();
}
diff --git a/libjava/classpath/java/security/cert/PKIXCertPathBuilderResult.java b/libjava/classpath/java/security/cert/PKIXCertPathBuilderResult.java
index 5091dd41298..fa160913c7d 100644
--- a/libjava/classpath/java/security/cert/PKIXCertPathBuilderResult.java
+++ b/libjava/classpath/java/security/cert/PKIXCertPathBuilderResult.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.security.cert;
+import gnu.java.lang.CPStringBuilder;
+
/**
* The result of calling the {@link
* CertPathBuilder#build(java.security.cert.CertPathParameters)} method
@@ -95,7 +97,7 @@ public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult
public String toString()
{
- StringBuffer buf = new StringBuffer(super.toString());
+ CPStringBuilder buf = new CPStringBuilder(super.toString());
buf.insert(buf.length() - 2, "; CertPath=" + certPath);
return buf.toString();
}
diff --git a/libjava/classpath/java/security/cert/PolicyQualifierInfo.java b/libjava/classpath/java/security/cert/PolicyQualifierInfo.java
index b50f3f31245..d4d9f99844d 100644
--- a/libjava/classpath/java/security/cert/PolicyQualifierInfo.java
+++ b/libjava/classpath/java/security/cert/PolicyQualifierInfo.java
@@ -124,7 +124,7 @@ PolicyQualifierId ::= OBJECT IDENTIFIER
*
* @return This structure's OID field.
*/
- public String getPolicyQualifierId()
+ public final String getPolicyQualifierId()
{
return oid.toString();
}
@@ -137,7 +137,7 @@ PolicyQualifierId ::= OBJECT IDENTIFIER
*
* @return The encoded form.
*/
- public byte[] getEncoded()
+ public final byte[] getEncoded()
{
return (byte[]) encoded.clone();
}
@@ -149,7 +149,7 @@ PolicyQualifierId ::= OBJECT IDENTIFIER
*
* @return The encoded qualifier.
*/
- public byte[] getPolicyQualifier()
+ public final byte[] getPolicyQualifier()
{
if (qualifier == null)
return new byte[0];
diff --git a/libjava/classpath/java/security/cert/X509CRLSelector.java b/libjava/classpath/java/security/cert/X509CRLSelector.java
index 56b171369fb..d412a1ae39e 100644
--- a/libjava/classpath/java/security/cert/X509CRLSelector.java
+++ b/libjava/classpath/java/security/cert/X509CRLSelector.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package java.security.cert;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
@@ -335,7 +336,7 @@ public class X509CRLSelector implements CRLSelector, Cloneable
*/
public String toString()
{
- StringBuffer str = new StringBuffer(X509CRLSelector.class.getName());
+ CPStringBuilder str = new CPStringBuilder(X509CRLSelector.class.getName());
String nl = SystemProperties.getProperty("line.separator");
String eol = ";" + nl;
diff --git a/libjava/classpath/java/security/cert/X509CertSelector.java b/libjava/classpath/java/security/cert/X509CertSelector.java
index 7a7db086b0a..4115fffacfa 100644
--- a/libjava/classpath/java/security/cert/X509CertSelector.java
+++ b/libjava/classpath/java/security/cert/X509CertSelector.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package java.security.cert;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
import gnu.java.security.OID;
import gnu.java.security.x509.GnuPKIExtension;
import gnu.java.security.x509.ext.CertificatePolicies;
@@ -1251,7 +1252,7 @@ public class X509CertSelector implements CertSelector, Cloneable
public String toString()
{
- StringBuffer str = new StringBuffer(X509CertSelector.class.getName());
+ CPStringBuilder str = new CPStringBuilder(X509CertSelector.class.getName());
String nl = SystemProperties.getProperty("line.separator");
String eol = ";" + nl;
str.append(" {").append(nl);
diff --git a/libjava/classpath/java/text/AttributedString.java b/libjava/classpath/java/text/AttributedString.java
index 6785bd3c58f..cb338bfe8df 100644
--- a/libjava/classpath/java/text/AttributedString.java
+++ b/libjava/classpath/java/text/AttributedString.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.text;
+import gnu.java.lang.CPStringBuilder;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -182,7 +184,7 @@ public class AttributedString
if ((begin < 0) || (end < begin) || end > aci.getEndIndex())
throw new IllegalArgumentException("Bad index values");
- StringBuffer sb = new StringBuffer("");
+ CPStringBuilder sb = new CPStringBuilder("");
// Get the valid attribute list
Set allAttribs = aci.getAllAttributeKeys();
diff --git a/libjava/classpath/java/text/ChoiceFormat.java b/libjava/classpath/java/text/ChoiceFormat.java
index 629701c171a..a552dd4a6c2 100644
--- a/libjava/classpath/java/text/ChoiceFormat.java
+++ b/libjava/classpath/java/text/ChoiceFormat.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.text;
+import gnu.java.lang.CPStringBuilder;
+
import java.util.Vector;
/**
@@ -98,8 +100,8 @@ public class ChoiceFormat extends NumberFormat
int index = 0, max = newPattern.length();
Vector stringVec = new Vector ();
Vector limitVec = new Vector ();
- StringBuffer buf = new StringBuffer ();
-
+ final CPStringBuilder buf = new CPStringBuilder ();
+
while (true)
{
// Find end of double.
@@ -442,7 +444,7 @@ public class ChoiceFormat extends NumberFormat
this.choiceLimits = (double[]) choiceLimits.clone();
}
- private void quoteString (StringBuffer dest, String text)
+ private void quoteString (CPStringBuilder dest, String text)
{
int max = text.length();
for (int i = 0; i < max; ++i)
@@ -473,7 +475,7 @@ public class ChoiceFormat extends NumberFormat
*/
public String toPattern ()
{
- StringBuffer result = new StringBuffer ();
+ CPStringBuilder result = new CPStringBuilder ();
for (int i = 0; i < choiceLimits.length; ++i)
{
result.append(choiceLimits[i]);
diff --git a/libjava/classpath/java/text/CollationElementIterator.java b/libjava/classpath/java/text/CollationElementIterator.java
index 08c5cb56361..f6e0022aa3d 100644
--- a/libjava/classpath/java/text/CollationElementIterator.java
+++ b/libjava/classpath/java/text/CollationElementIterator.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.text;
+import gnu.java.lang.CPStringBuilder;
+
import java.util.ArrayList;
/* Written using "Java Class Libraries", 2nd edition, plus online
@@ -416,7 +418,7 @@ public final class CollationElementIterator
*/
public void setText(CharacterIterator source)
{
- StringBuffer expand = new StringBuffer();
+ CPStringBuilder expand = new CPStringBuilder();
// For now assume we read from the beginning of the string.
for (char c = source.first();
diff --git a/libjava/classpath/java/text/Collator.java b/libjava/classpath/java/text/Collator.java
index 16ee6b1241b..d6cb5ac0eb9 100644
--- a/libjava/classpath/java/text/Collator.java
+++ b/libjava/classpath/java/text/Collator.java
@@ -406,10 +406,12 @@ public abstract class Collator implements Comparator<Object>, Cloneable
// Decompose a single character and append results to the buffer.
// FIXME: for libgcj this is a native method which handles
// decomposition. For Classpath, for now, it does nothing.
+ /*
final void decomposeCharacter (char c, StringBuffer buf)
{
buf.append (c);
}
+ */
/**
* This is the current collation decomposition setting.
diff --git a/libjava/classpath/java/text/DateFormat.java b/libjava/classpath/java/text/DateFormat.java
index 53b757e88b6..dabcb867079 100644
--- a/libjava/classpath/java/text/DateFormat.java
+++ b/libjava/classpath/java/text/DateFormat.java
@@ -219,80 +219,6 @@ public abstract class DateFormat extends Format implements Cloneable
* In the U.S. locale, this is 'z'.
*/
public static final int TIMEZONE_FIELD = 17;
- /**
- * Represents the position of the ISO year
- * pattern character in the array of
- * localized pattern characters.
- * In the U.S. locale, this is 'Y'.
- * This is a GNU extension in accordance with
- * the CLDR data used. This value may
- * differ from the normal year value.
- */
- public static final int ISO_YEAR_FIELD = 18;
- /**
- * Represents the position of the localized
- * day of the week pattern character in the
- * array of localized pattern characters.
- * In the U.S. locale, this is 'e'.
- * This is a GNU extension in accordance with
- * the CLDR data used. This value only
- * differs from the day of the week with
- * numeric formatting, in which case the
- * locale's first day of the week is used.
- */
- public static final int LOCALIZED_DAY_OF_WEEK_FIELD = 19;
- /**
- * Represents the position of the extended year
- * pattern character in the array of
- * localized pattern characters.
- * In the U.S. locale, this is 'u'.
- * This is a GNU extension in accordance with
- * the CLDR data used. This value modifies
- * the year value, so as to incorporate the era.
- * For example, in the Gregorian calendar system,
- * the extended year is negative instead of being
- * marked as BC.
- */
- public static final int EXTENDED_YEAR_FIELD = 20;
- /**
- * Represents the position of the modified Julian
- * day pattern character in the array of
- * localized pattern characters.
- * In the U.S. locale, this is 'g'.
- * This is a GNU extension in accordance with
- * the CLDR data used. This value differs
- * from the standard Julian day in that days
- * are marked from midnight onwards rather than
- * noon, and the local time zone affects the value.
- * In simple terms, it can be thought of as all
- * the date fields represented as a single number.
- */
- public static final int MODIFIED_JULIAN_DAY_FIELD = 21;
- /**
- * Represents the position of the millisecond
- * in the day pattern character in the array of
- * localized pattern characters.
- * In the U.S. locale, this is 'A'.
- * This is a GNU extension in accordance with
- * the CLDR data used. This value represents
- * all the time fields (excluding the time zone)
- * numerically, giving the number of milliseconds
- * into the day (e.g. 10 in the morning would
- * be 10 * 60 * 60 * 1000). Any daylight savings
- * offset also affects this value.
- */
- public static final int MILLISECOND_IN_DAY_FIELD = 22;
- /**
- * Represents the position of the RFC822
- * timezone pattern character in the array of
- * localized pattern characters.
- * In the U.S. locale, this is 'Z'.
- * This is a GNU extension in accordance with
- * the CLDR data used. The value is the offset
- * of the current time from GMT e.g. -0500 would
- * be five hours prior to GMT.
- */
- public static final int RFC822_TIMEZONE_FIELD = 23;
public static class Field extends Format.Field
{
@@ -336,18 +262,6 @@ public abstract class DateFormat extends Format implements Cloneable
= new Field("hour0", Calendar.HOUR);
public static final DateFormat.Field TIME_ZONE
= new Field("timezone", Calendar.ZONE_OFFSET);
- public static final DateFormat.Field ISO_YEAR
- = new Field("iso year", Calendar.YEAR);
- public static final DateFormat.Field LOCALIZED_DAY_OF_WEEK
- = new Field("localized day of week", Calendar.DAY_OF_WEEK);
- public static final DateFormat.Field EXTENDED_YEAR
- = new Field("extended year", Calendar.YEAR);
- public static final DateFormat.Field MODIFIED_JULIAN_DAY
- = new Field("julian day", -1);
- public static final DateFormat.Field MILLISECOND_IN_DAY
- = new Field("millisecond in day", -1);
- public static final DateFormat.Field RFC822_TIME_ZONE
- = new Field("rfc822 timezone", Calendar.ZONE_OFFSET);
static final DateFormat.Field[] allFields =
{
@@ -355,9 +269,7 @@ public abstract class DateFormat extends Format implements Cloneable
HOUR_OF_DAY0, MINUTE, SECOND, MILLISECOND,
DAY_OF_WEEK, DAY_OF_YEAR, DAY_OF_WEEK_IN_MONTH,
WEEK_OF_YEAR, WEEK_OF_MONTH, AM_PM, HOUR1, HOUR0,
- TIME_ZONE, ISO_YEAR, LOCALIZED_DAY_OF_WEEK,
- EXTENDED_YEAR, MODIFIED_JULIAN_DAY, MILLISECOND_IN_DAY,
- RFC822_TIME_ZONE
+ TIME_ZONE
};
// For deserialization
diff --git a/libjava/classpath/java/text/DateFormatSymbols.java b/libjava/classpath/java/text/DateFormatSymbols.java
index 406376a0ff5..ed953dd0733 100644
--- a/libjava/classpath/java/text/DateFormatSymbols.java
+++ b/libjava/classpath/java/text/DateFormatSymbols.java
@@ -40,12 +40,17 @@ package java.text;
import gnu.java.locale.LocaleHelper;
+import java.io.IOException;
+
import java.text.spi.DateFormatSymbolsProvider;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.MissingResourceException;
+import java.util.Properties;
import java.util.ResourceBundle;
import java.util.ServiceLoader;
import java.util.TimeZone;
@@ -74,6 +79,27 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable
String[] weekdays;
/**
+ * The set of properties for obtaining the metazone data.
+ */
+ private static transient final Properties properties;
+
+ /**
+ * Reads in the properties.
+ */
+ static
+ {
+ properties = new Properties();
+ try
+ {
+ properties.load(DateFormatSymbols.class.getResourceAsStream("metazones.properties"));
+ }
+ catch (IOException exception)
+ {
+ System.out.println("Failed to load weeks resource: " + exception);
+ }
+ }
+
+ /**
* The timezone strings supplied by the runtime.
*/
private String[][] runtimeZoneStrings;
@@ -109,11 +135,71 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable
List<String[]> allZones = new ArrayList<String[]>();
try
{
- int index = 0;
- String data = res.getString("zoneStrings");
- String[] zones = data.split("\u00a9");
- for (int a = 0; a < zones.length; ++a)
- allZones.add(zones[a].split("\u00ae"));
+ Map<String,String[]> systemZones = new HashMap<String,String[]>();
+ while (true)
+ {
+ int index = 0;
+ String country = locale.getCountry();
+ String data = res.getString("zoneStrings");
+ String[] zones = data.split("\u00a9");
+ for (int a = 0; a < zones.length; ++a)
+ {
+ String[] strings = zones[a].split("\u00ae");
+ String type = properties.getProperty(strings[0] + "." + country);
+ if (type == null)
+ type = properties.getProperty(strings[0] + ".DEFAULT");
+ if (type != null)
+ strings[0] = type;
+ if (strings.length < 5)
+ {
+ String[] newStrings = new String[5];
+ System.arraycopy(strings, 0, newStrings, 0, strings.length);
+ for (int b = strings.length; b < newStrings.length; ++b)
+ newStrings[b] = "";
+ strings = newStrings;
+ }
+ String[] existing = systemZones.get(strings[0]);
+ if (existing != null && existing.length > 1)
+ {
+ for (int b = 1; b < existing.length; ++b)
+ if (!existing[b].equals(""))
+ strings[b] = existing[b];
+ }
+ systemZones.put(strings[0], strings);
+ }
+ if (res.getLocale() == Locale.ROOT)
+ break;
+ else
+ res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
+ LocaleHelper.getFallbackLocale(res.getLocale()),
+ ClassLoader.getSystemClassLoader());
+ }
+ /* Final sanity check for missing values */
+ for (String[] zstrings : systemZones.values())
+ {
+ if (zstrings[1].equals("") && zstrings[2].equals(""))
+ {
+ for (Map.Entry<Object,Object> entry : properties.entrySet())
+ {
+ String val = (String) entry.getValue();
+ if (val.equals(zstrings[0]))
+ {
+ String key = (String) entry.getKey();
+ String metazone = key.substring(0, key.indexOf("."));
+ String type = properties.getProperty(metazone + "." + locale.getCountry());
+ if (type == null)
+ type = properties.getProperty(metazone + ".DEFAULT");
+ if (type != null)
+ {
+ String[] ostrings = systemZones.get(type);
+ zstrings[1] = ostrings[1];
+ zstrings[2] = ostrings[2];
+ }
+ }
+ }
+ }
+ }
+ allZones.addAll(systemZones.values());
}
catch (MissingResourceException e)
{
@@ -189,9 +275,9 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable
shortMonths = getStringArray(res, "shortMonths");
shortWeekdays = getStringArray(res, "shortWeekdays");
weekdays = getStringArray(res, "weekdays");
- runtimeZoneStrings = getZoneStrings(res, locale);
dateFormats = formatsForKey(res, "DateFormat");
timeFormats = formatsForKey(res, "TimeFormat");
+ runtimeZoneStrings = getZoneStrings(res, locale);
}
/**
diff --git a/libjava/classpath/java/text/DecimalFormat.java b/libjava/classpath/java/text/DecimalFormat.java
index 61732c1123d..425174437a7 100644
--- a/libjava/classpath/java/text/DecimalFormat.java
+++ b/libjava/classpath/java/text/DecimalFormat.java
@@ -43,6 +43,8 @@ exception statement from your version. */
package java.text;
+import gnu.java.lang.CPStringBuilder;
+
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -71,7 +73,7 @@ import java.util.Locale;
* Generally, to get an instance of DecimalFormat you should call the factory
* methods in the <code>NumberFormat</code> base class.
*
- * @author Mario Torre <neugens@limasoftware.net>
+ * @author Mario Torre (neugens@limasoftware.net)
* @author Tom Tromey (tromey@cygnus.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
*/
@@ -310,7 +312,7 @@ public class DecimalFormat extends NumberFormat
* field. If used on output defines the offsets of the alignment field.
* @return The String representation of this long.
*/
- public StringBuffer format(Object obj, StringBuffer sbuf, FieldPosition pos)
+ public final StringBuffer format(Object obj, StringBuffer sbuf, FieldPosition pos)
{
if (obj instanceof BigInteger)
{
@@ -588,7 +590,7 @@ public class DecimalFormat extends NumberFormat
return Double.valueOf(Double.NaN);
// this will be our final number
- StringBuffer number = new StringBuffer();
+ CPStringBuilder number = new CPStringBuilder();
// special character
char minus = symbols.getMinusSign();
@@ -799,7 +801,30 @@ public class DecimalFormat extends NumberFormat
*/
public void setCurrency(Currency currency)
{
- symbols.setCurrency(currency);
+ Currency current = symbols.getCurrency();
+ if (current != currency)
+ {
+ String oldSymbol = symbols.getCurrencySymbol();
+ int len = oldSymbol.length();
+ symbols.setCurrency(currency);
+ String newSymbol = symbols.getCurrencySymbol();
+ int posPre = positivePrefix.indexOf(oldSymbol);
+ if (posPre != -1)
+ positivePrefix = positivePrefix.substring(0, posPre) +
+ newSymbol + positivePrefix.substring(posPre+len);
+ int negPre = negativePrefix.indexOf(oldSymbol);
+ if (negPre != -1)
+ negativePrefix = negativePrefix.substring(0, negPre) +
+ newSymbol + negativePrefix.substring(negPre+len);
+ int posSuf = positiveSuffix.indexOf(oldSymbol);
+ if (posSuf != -1)
+ positiveSuffix = positiveSuffix.substring(0, posSuf) +
+ newSymbol + positiveSuffix.substring(posSuf+len);
+ int negSuf = negativeSuffix.indexOf(oldSymbol);
+ if (negSuf != -1)
+ negativeSuffix = negativeSuffix.substring(0, negSuf) +
+ newSymbol + negativeSuffix.substring(negSuf+len);
+ }
}
/**
@@ -1003,7 +1028,7 @@ public class DecimalFormat extends NumberFormat
*/
private String patternChars (DecimalFormatSymbols syms)
{
- StringBuffer buf = new StringBuffer ();
+ CPStringBuilder buf = new CPStringBuilder ();
buf.append(syms.getDecimalSeparator());
buf.append(syms.getDigit());
@@ -1028,9 +1053,9 @@ public class DecimalFormat extends NumberFormat
* @param patChars
* @return A StringBuffer with special characters quoted.
*/
- private StringBuffer quoteFix(String text, String patChars)
+ private CPStringBuilder quoteFix(String text, String patChars)
{
- StringBuffer buf = new StringBuffer();
+ CPStringBuilder buf = new CPStringBuilder();
int len = text.length();
char ch;
@@ -1058,7 +1083,7 @@ public class DecimalFormat extends NumberFormat
*/
private String computePattern(DecimalFormatSymbols symbols)
{
- StringBuffer mainPattern = new StringBuffer();
+ StringBuilder mainPattern = new StringBuilder();
// We have to at least emit a zero for the minimum number of
// digits. Past that we need hash marks up to the grouping
@@ -1225,7 +1250,7 @@ public class DecimalFormat extends NumberFormat
private int scanFix(String pattern, DecimalFormatSymbols sourceSymbols,
int start, boolean prefix)
{
- StringBuffer buffer = new StringBuffer();
+ CPStringBuilder buffer = new CPStringBuilder();
// the number portion is always delimited by one of those
// characters
@@ -1296,7 +1321,7 @@ public class DecimalFormat extends NumberFormat
currencySymbol = this.symbols.getCurrencySymbol();
// if \u00A4 is doubled, we use the international currency symbol
- if (i < len && pattern.charAt(i + 1) == '\u00A4')
+ if ((i + 1) < len && pattern.charAt(i + 1) == '\u00A4')
{
currencySymbol = this.symbols.getInternationalCurrencySymbol();
i++;
@@ -1320,7 +1345,7 @@ public class DecimalFormat extends NumberFormat
else if (ch == '\'')
{
// QUOTE
- if (i < len && pattern.charAt(i + 1) == '\'')
+ if ((i + 1) < len && pattern.charAt(i + 1) == '\'')
{
// we need to add ' to the buffer
buffer.append(ch);
@@ -1599,7 +1624,7 @@ public class DecimalFormat extends NumberFormat
DecimalFormatSymbols sourceSymbols,
int start)
{
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
// the number portion is always delimited by one of those
// characters
@@ -1692,7 +1717,7 @@ public class DecimalFormat extends NumberFormat
else if (ch == '\'')
{
// QUOTE
- if (i < len && pattern.charAt(i + 1) == '\'')
+ if ((i + 1) < len && pattern.charAt(i + 1) == '\'')
{
// we need to add ' to the buffer
buffer.append(ch);
@@ -2180,7 +2205,7 @@ public class DecimalFormat extends NumberFormat
else
{
char zero = symbols.getZeroDigit();
- StringBuffer _result = new StringBuffer(src);
+ CPStringBuilder _result = new CPStringBuilder(src);
for (int i = len; i < minimumDigits; i++)
{
_result.append(zero);
diff --git a/libjava/classpath/java/text/DecimalFormatSymbols.java b/libjava/classpath/java/text/DecimalFormatSymbols.java
index f87ebbf138f..b7edf39c45e 100644
--- a/libjava/classpath/java/text/DecimalFormatSymbols.java
+++ b/libjava/classpath/java/text/DecimalFormatSymbols.java
@@ -170,6 +170,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable
{
res = null;
}
+ locale = loc;
currency = Currency.getInstance("XXX");
currencySymbol = "?";
intlCurrencySymbol = "XXX";
@@ -204,7 +205,6 @@ public class DecimalFormatSymbols implements Cloneable, Serializable
percent = safeGetChar (res, "percent", '%');
perMill = safeGetChar (res, "perMill", '\u2030');
zeroDigit = safeGetChar (res, "zeroDigit", '0');
- locale = loc;
}
/**
@@ -430,7 +430,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable
public void setCurrency (Currency currency)
{
intlCurrencySymbol = currency.getCurrencyCode();
- currencySymbol = currency.getSymbol();
+ currencySymbol = currency.getSymbol(locale);
this.currency = currency;
}
diff --git a/libjava/classpath/java/text/Format.java b/libjava/classpath/java/text/Format.java
index 38fda34ff64..7159f468552 100644
--- a/libjava/classpath/java/text/Format.java
+++ b/libjava/classpath/java/text/Format.java
@@ -81,7 +81,7 @@ public abstract class Format implements Serializable, Cloneable
* It performs no actions, but acts as a default constructor for
* subclasses.
*/
- public Format ()
+ protected Format ()
{
}
diff --git a/libjava/classpath/java/text/MessageFormat.java b/libjava/classpath/java/text/MessageFormat.java
index 5a595f57615..c5579bff1f0 100644
--- a/libjava/classpath/java/text/MessageFormat.java
+++ b/libjava/classpath/java/text/MessageFormat.java
@@ -194,7 +194,7 @@ public class MessageFormat extends Format
// Helper that returns the text up to the next format opener. The
// text is put into BUFFER. Returns index of character after end of
// string. Throws IllegalArgumentException on error.
- private static int scanString(String pat, int index, StringBuffer buffer)
+ private static int scanString(String pat, int index, StringBuilder buffer)
{
int max = pat.length();
buffer.setLength(0);
@@ -234,7 +234,7 @@ public class MessageFormat extends Format
// This helper retrieves a single part of a format element. Returns
// the index of the terminating character.
private static int scanFormatElement(String pat, int index,
- StringBuffer buffer, char term)
+ StringBuilder buffer, char term)
{
int max = pat.length();
buffer.setLength(0);
@@ -281,7 +281,7 @@ public class MessageFormat extends Format
// This is used to parse a format element and whatever non-format
// text might trail it.
- private static int scanFormat(String pat, int index, StringBuffer buffer,
+ private static int scanFormat(String pat, int index, StringBuilder buffer,
Vector elts, Locale locale)
{
MessageFormatElement mfe = new MessageFormatElement ();
@@ -342,7 +342,7 @@ public class MessageFormat extends Format
{
pattern = newPattern;
- StringBuffer tempBuffer = new StringBuffer ();
+ StringBuilder tempBuffer = new StringBuilder ();
int index = scanString (newPattern, 0, tempBuffer);
leader = tempBuffer.toString();
diff --git a/libjava/classpath/java/text/NumberFormat.java b/libjava/classpath/java/text/NumberFormat.java
index 4a72f443a7b..0a436d00439 100644
--- a/libjava/classpath/java/text/NumberFormat.java
+++ b/libjava/classpath/java/text/NumberFormat.java
@@ -653,7 +653,7 @@ public abstract class NumberFormat extends Format implements Cloneable
/**
* This is a default constructor for use by subclasses.
*/
- public NumberFormat ()
+ protected NumberFormat ()
{
}
diff --git a/libjava/classpath/java/text/RuleBasedCollator.java b/libjava/classpath/java/text/RuleBasedCollator.java
index 7ec18dcc92f..fdd1446cc0c 100644
--- a/libjava/classpath/java/text/RuleBasedCollator.java
+++ b/libjava/classpath/java/text/RuleBasedCollator.java
@@ -404,7 +404,7 @@ public class RuleBasedCollator extends Collator
{
boolean ignoreChars = (base_offset == 0);
int operator = -1;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
boolean doubleQuote = false;
boolean eatingChars = false;
boolean nextIsModifier = false;
diff --git a/libjava/classpath/java/text/SimpleDateFormat.java b/libjava/classpath/java/text/SimpleDateFormat.java
index 934fb42e2a1..4dcda4f487c 100644
--- a/libjava/classpath/java/text/SimpleDateFormat.java
+++ b/libjava/classpath/java/text/SimpleDateFormat.java
@@ -40,6 +40,8 @@ exception statement from your version. */
package java.text;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.text.AttributedFormatBuffer;
import gnu.java.text.FormatBuffer;
import gnu.java.text.FormatCharacterIterator;
@@ -61,6 +63,8 @@ import java.util.regex.Pattern;
/**
* SimpleDateFormat provides convenient methods for parsing and formatting
* dates using Gregorian calendars (see java.util.GregorianCalendar).
+ * This class is not thread-safe; external synchronisation should be applied
+ * if an instance is to be accessed from multiple threads.
*/
public class SimpleDateFormat extends DateFormat
{
@@ -139,9 +143,9 @@ public class SimpleDateFormat extends DateFormat
*/
public String toString()
{
- StringBuilder builder;
+ CPStringBuilder builder;
- builder = new StringBuilder(getClass().getName());
+ builder = new CPStringBuilder(getClass().getName());
builder.append("[field=");
builder.append(field);
builder.append(", size=");
@@ -231,10 +235,16 @@ public class SimpleDateFormat extends DateFormat
*/
private static final long serialVersionUID = 4774881970558875024L;
- // This string is specified in the root of the CLDR. We set it here
- // rather than doing a DateFormatSymbols(Locale.US).getLocalPatternChars()
- // since someone could theoretically change those values (though unlikely).
- private static final String standardChars = "GyMdkHmsSEDFwWahKzYeugAZ";
+ // This string is specified in the Java class libraries.
+ private static final String standardChars = "GyMdkHmsSEDFwWahKzZ";
+
+ /**
+ * Represents the position of the RFC822 timezone pattern character
+ * in the array of localized pattern characters. In the
+ * U.S. locale, this is 'Z'. The value is the offset of the current
+ * time from GMT e.g. -0500 would be five hours prior to GMT.
+ */
+ private static final int RFC822_TIMEZONE_FIELD = 18;
/**
* Reads the serialized version of this object.
@@ -322,7 +332,7 @@ public class SimpleDateFormat extends DateFormat
// Look for the terminating quote. However, if we
// see a '', that represents a literal quote and
// we must iterate.
- StringBuilder buf = new StringBuilder();
+ CPStringBuilder buf = new CPStringBuilder();
int oldPos = i + 1;
do
{
@@ -372,7 +382,7 @@ public class SimpleDateFormat extends DateFormat
*/
public String toString()
{
- StringBuilder output = new StringBuilder(getClass().getName());
+ CPStringBuilder output = new CPStringBuilder(getClass().getName());
output.append("[tokens=");
output.append(tokens);
output.append(", formatData=");
@@ -554,7 +564,7 @@ public class SimpleDateFormat extends DateFormat
String oldChars, String newChars)
{
int len = pattern.length();
- StringBuilder buf = new StringBuilder(len);
+ CPStringBuilder buf = new CPStringBuilder(len);
boolean quoted = false;
for (int i = 0; i < len; i++)
{
@@ -802,7 +812,7 @@ public class SimpleDateFormat extends DateFormat
buffer.append (zoneID);
break;
case RFC822_TIMEZONE_FIELD:
- buffer.setDefaultAttribute(DateFormat.Field.RFC822_TIME_ZONE);
+ buffer.setDefaultAttribute(DateFormat.Field.TIME_ZONE);
int pureMinutes = (calendar.get(Calendar.ZONE_OFFSET) +
calendar.get(Calendar.DST_OFFSET)) / (1000 * 60);
String sign = (pureMinutes < 0) ? "-" : "+";
diff --git a/libjava/classpath/java/util/AbstractCollection.java b/libjava/classpath/java/util/AbstractCollection.java
index ef74342237a..a11654ebbaf 100644
--- a/libjava/classpath/java/util/AbstractCollection.java
+++ b/libjava/classpath/java/util/AbstractCollection.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.lang.reflect.Array;
/**
@@ -434,7 +436,7 @@ public abstract class AbstractCollection<E>
public String toString()
{
Iterator itr = iterator();
- StringBuffer r = new StringBuffer("[");
+ CPStringBuilder r = new CPStringBuilder("[");
boolean hasNext = itr.hasNext();
while (hasNext)
{
diff --git a/libjava/classpath/java/util/AbstractMap.java b/libjava/classpath/java/util/AbstractMap.java
index 02a30a294de..5d59db9a666 100644
--- a/libjava/classpath/java/util/AbstractMap.java
+++ b/libjava/classpath/java/util/AbstractMap.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Serializable;
/**
@@ -524,7 +526,7 @@ public abstract class AbstractMap<K, V> implements Map<K, V>
public String toString()
{
Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
- StringBuilder r = new StringBuilder("{");
+ CPStringBuilder r = new CPStringBuilder("{");
for (int pos = size(); pos > 0; pos--)
{
Map.Entry<K, V> entry = entries.next();
diff --git a/libjava/classpath/java/util/ArrayList.java b/libjava/classpath/java/util/ArrayList.java
index 0693049b53a..1fb25d80152 100644
--- a/libjava/classpath/java/util/ArrayList.java
+++ b/libjava/classpath/java/util/ArrayList.java
@@ -472,8 +472,7 @@ public class ArrayList<E> extends AbstractList<E>
// use of a negative index will cause an ArrayIndexOutOfBoundsException,
// a subclass of the required exception, with no effort on our part.
if (index > size)
- throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
- + size);
+ raiseBoundsError(index);
}
/**
@@ -488,11 +487,25 @@ public class ArrayList<E> extends AbstractList<E>
// use of a negative index will cause an ArrayIndexOutOfBoundsException,
// a subclass of the required exception, with no effort on our part.
if (index >= size)
- throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
- + size);
+ raiseBoundsError(index);
}
/**
+ * Raise the ArrayIndexOfOutBoundsException.
+ *
+ * @param index the index of the access
+ * @throws IndexOutOfBoundsException unconditionally
+ */
+ private void raiseBoundsError(int index)
+ {
+ // Implementaion note: put in a separate method to make the JITs job easier
+ // (separate common from uncommon code at method boundaries when trivial to
+ // do so).
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+ }
+
+
+ /**
* Remove from this list all elements contained in the given collection.
* This is not public, due to Sun's API, but this performs in linear
* time while the default behavior of AbstractList would be quadratic.
diff --git a/libjava/classpath/java/util/Arrays.java b/libjava/classpath/java/util/Arrays.java
index e5f772778c2..d154eb1d1ba 100644
--- a/libjava/classpath/java/util/Arrays.java
+++ b/libjava/classpath/java/util/Arrays.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Serializable;
import java.lang.reflect.Array;
@@ -2935,7 +2937,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -2957,7 +2959,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -2979,7 +2981,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -3001,7 +3003,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -3023,7 +3025,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -3045,7 +3047,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -3067,7 +3069,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -3089,7 +3091,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -3111,7 +3113,7 @@ public class Arrays
{
if (v == null)
return "null";
- StringBuilder b = new StringBuilder("[");
+ CPStringBuilder b = new CPStringBuilder("[");
for (int i = 0; i < v.length; ++i)
{
if (i > 0)
@@ -3122,7 +3124,7 @@ public class Arrays
return b.toString();
}
- private static void deepToString(Object[] v, StringBuilder b, HashSet seen)
+ private static void deepToString(Object[] v, CPStringBuilder b, HashSet seen)
{
b.append("[");
for (int i = 0; i < v.length; ++i)
@@ -3171,7 +3173,7 @@ public class Arrays
if (v == null)
return "null";
HashSet seen = new HashSet();
- StringBuilder b = new StringBuilder();
+ CPStringBuilder b = new CPStringBuilder();
deepToString(v, b, seen);
return b.toString();
}
diff --git a/libjava/classpath/java/util/BitSet.java b/libjava/classpath/java/util/BitSet.java
index e4f923b7f22..13bf8a13cff 100644
--- a/libjava/classpath/java/util/BitSet.java
+++ b/libjava/classpath/java/util/BitSet.java
@@ -36,6 +36,9 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.util;
+
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Serializable;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
@@ -687,7 +690,7 @@ public class BitSet implements Cloneable, Serializable
*/
public String toString()
{
- StringBuffer r = new StringBuffer("{");
+ CPStringBuilder r = new CPStringBuilder("{");
boolean first = true;
for (int i = 0; i < bits.length; ++i)
{
diff --git a/libjava/classpath/java/util/Calendar.java b/libjava/classpath/java/util/Calendar.java
index 712296b1a2a..0449e126db8 100644
--- a/libjava/classpath/java/util/Calendar.java
+++ b/libjava/classpath/java/util/Calendar.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -485,6 +487,28 @@ public abstract class Calendar
}
/**
+ * The set of properties for obtaining the minimum number of days in
+ * the first week.
+ */
+ private static transient final Properties properties;
+
+ /**
+ * Reads in the properties.
+ */
+ static
+ {
+ properties = new Properties();
+ try
+ {
+ properties.load(Calendar.class.getResourceAsStream("weeks.properties"));
+ }
+ catch (IOException exception)
+ {
+ System.out.println("Failed to load weeks resource: " + exception);
+ }
+ }
+
+ /**
* Constructs a new Calendar with the default time zone and the default
* locale.
*/
@@ -505,9 +529,13 @@ public abstract class Calendar
lenient = true;
String[] days = { "", "sun", "mon", "tue", "wed", "thu", "fri", "sat" };
- ResourceBundle rb = getBundle(locale);
- String min = (String) rb.getObject("minNumberOfDaysInFirstWeek");
- String first = (String) rb.getObject("firstDayOfWeek");
+ String country = locale.getCountry();
+ String min = properties.getProperty("minDays." + country);
+ if (min == null)
+ min = properties.getProperty("minDays.DEFAULT");
+ String first = properties.getProperty("firstDay." + country);
+ if (first == null)
+ first = properties.getProperty("firstDay.DEFAULT");
try
{
if (min != null)
@@ -1328,7 +1356,7 @@ public abstract class Calendar
*/
public String toString()
{
- StringBuilder sb = new StringBuilder(getClass().getName());
+ CPStringBuilder sb = new CPStringBuilder(getClass().getName());
sb.append('[');
sb.append("time=");
if (isTimeSet)
diff --git a/libjava/classpath/java/util/Collections.java b/libjava/classpath/java/util/Collections.java
index ae2010f1ce5..066c9d53893 100644
--- a/libjava/classpath/java/util/Collections.java
+++ b/libjava/classpath/java/util/Collections.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Serializable;
/**
@@ -1135,7 +1137,7 @@ public class Collections
*/
public String toString()
{
- StringBuffer r = new StringBuffer("{");
+ CPStringBuilder r = new CPStringBuilder("{");
for (int i = n - 1; --i > 0; )
r.append(element).append(", ");
r.append(element).append("}");
diff --git a/libjava/classpath/java/util/Currency.java b/libjava/classpath/java/util/Currency.java
index b5da13c37f1..11235f14b35 100644
--- a/libjava/classpath/java/util/Currency.java
+++ b/libjava/classpath/java/util/Currency.java
@@ -139,7 +139,7 @@ public final class Currency
}
catch (IOException exception)
{
- System.out.println("Failed to load currency resource: " + exception);
+ throw new InternalError("Failed to load currency resource: " + exception);
}
}
diff --git a/libjava/classpath/java/util/Date.java b/libjava/classpath/java/util/Date.java
index 8646c19175e..5f83cd06cb3 100644
--- a/libjava/classpath/java/util/Date.java
+++ b/libjava/classpath/java/util/Date.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -722,7 +724,7 @@ public class Date
boolean localTimezone = true;
// Trim out any nested stuff in parentheses now to make parsing easier.
- StringBuilder buf = new StringBuilder();
+ CPStringBuilder buf = new CPStringBuilder();
int parenNesting = 0;
int len = string.length();
for (int i = 0; i < len; i++)
diff --git a/libjava/classpath/java/util/Formatter.java b/libjava/classpath/java/util/Formatter.java
index 82130782e0f..9217d93b6e9 100644
--- a/libjava/classpath/java/util/Formatter.java
+++ b/libjava/classpath/java/util/Formatter.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
@@ -470,7 +472,7 @@ public final class Formatter
* @param width the width of the numeric value.
* @param isNegative true if the value is negative.
*/
- private void applyLocalization(StringBuilder builder, int flags, int width,
+ private void applyLocalization(CPStringBuilder builder, int flags, int width,
boolean isNegative)
{
DecimalFormatSymbols dfsyms;
@@ -741,9 +743,9 @@ public final class Formatter
* @param conversion the conversion character.
* @return the result.
*/
- private StringBuilder basicIntegralConversion(Object arg, int flags,
- int width, int precision,
- int radix, char conversion)
+ private CPStringBuilder basicIntegralConversion(Object arg, int flags,
+ int width, int precision,
+ int radix, char conversion)
{
assert radix == 8 || radix == 10 || radix == 16;
noPrecision(precision);
@@ -798,7 +800,7 @@ public final class Formatter
else
throw new IllegalFormatConversionException(conversion, arg.getClass());
- return new StringBuilder(result);
+ return new CPStringBuilder(result);
}
/**
@@ -819,9 +821,9 @@ public final class Formatter
{
assert radix == 8 || radix == 16;
- StringBuilder builder = basicIntegralConversion(arg, flags, width,
- precision, radix,
- conversion);
+ CPStringBuilder builder = basicIntegralConversion(arg, flags, width,
+ precision, radix,
+ conversion);
int insertPoint = 0;
// Insert the sign.
@@ -897,9 +899,9 @@ public final class Formatter
int precision, char conversion)
throws IOException
{
- StringBuilder builder = basicIntegralConversion(arg, flags, width,
- precision, 10,
- conversion);
+ CPStringBuilder builder = basicIntegralConversion(arg, flags, width,
+ precision, 10,
+ conversion);
boolean isNegative = false;
if (builder.charAt(0) == '-')
{
@@ -920,7 +922,7 @@ public final class Formatter
* @param conversion the formatting character to specify the type of data.
* @param syms the date formatting symbols.
*/
- private void singleDateTimeConversion(StringBuilder builder, Calendar cal,
+ private void singleDateTimeConversion(CPStringBuilder builder, Calendar cal,
char conversion,
DateFormatSymbols syms)
{
@@ -1151,7 +1153,7 @@ public final class Formatter
else
syms = new DateFormatSymbols(fmtLocale);
- StringBuilder result = new StringBuilder();
+ CPStringBuilder result = new CPStringBuilder();
singleDateTimeConversion(result, cal, subConversion, syms);
genericFormat(result.toString(), flags, width, precision);
diff --git a/libjava/classpath/java/util/Hashtable.java b/libjava/classpath/java/util/Hashtable.java
index 07bd9469318..0851de8249a 100644
--- a/libjava/classpath/java/util/Hashtable.java
+++ b/libjava/classpath/java/util/Hashtable.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -579,7 +581,7 @@ public class Hashtable<K, V> extends Dictionary<K, V>
// would repeatedly re-lock/release the monitor, we directly use the
// unsynchronized EntryIterator instead.
Iterator<Map.Entry<K, V>> entries = new EntryIterator();
- StringBuilder r = new StringBuilder("{");
+ CPStringBuilder r = new CPStringBuilder("{");
for (int pos = size; pos > 0; pos--)
{
r.append(entries.next());
diff --git a/libjava/classpath/java/util/Locale.java b/libjava/classpath/java/util/Locale.java
index cd372f24551..c28709f95d6 100644
--- a/libjava/classpath/java/util/Locale.java
+++ b/libjava/classpath/java/util/Locale.java
@@ -39,6 +39,9 @@ exception statement from your version. */
package java.util;
import gnu.classpath.SystemProperties;
+
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.locale.LocaleHelper;
import java.io.IOException;
@@ -548,7 +551,7 @@ public final class Locale implements Serializable, Cloneable
return "";
else if (country.length() == 0 && variant.length() == 0)
return language;
- StringBuffer result = new StringBuffer(language);
+ CPStringBuilder result = new CPStringBuilder(language);
result.append('_').append(country);
if (variant.length() != 0)
result.append('_').append(variant);
@@ -922,7 +925,7 @@ public final class Locale implements Serializable, Cloneable
*/
public String getDisplayName(Locale locale)
{
- StringBuffer result = new StringBuffer();
+ CPStringBuilder result = new CPStringBuilder();
int count = 0;
String[] delimiters = {"", " (", ","};
if (language.length() != 0)
diff --git a/libjava/classpath/java/util/Properties.java b/libjava/classpath/java/util/Properties.java
index e294fee7ea9..a57004b3415 100644
--- a/libjava/classpath/java/util/Properties.java
+++ b/libjava/classpath/java/util/Properties.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -46,6 +48,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.io.Reader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
@@ -155,7 +158,7 @@ public class Properties extends Hashtable<Object, Object>
}
/**
- * Reads a property list from an input stream. The stream should
+ * Reads a property list from a character stream. The stream should
* have the following format: <br>
*
* An empty line or a line starting with <code>#</code> or
@@ -187,15 +190,14 @@ weekdays: Sunday,Monday,Tuesday,Wednesday,\\
# The safest way to include a space at the end of a value:
label = Name:\\u0020</pre>
*
- * @param inStream the input stream
+ * @param inReader the input {@link java.io.Reader}.
* @throws IOException if an error occurred when reading the input
* @throws NullPointerException if in is null
+ * @since 1.6
*/
- public void load(InputStream inStream) throws IOException
+ public void load(Reader inReader) throws IOException
{
- // The spec says that the file must be encoded using ISO-8859-1.
- BufferedReader reader =
- new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));
+ BufferedReader reader = new BufferedReader(inReader);
String line;
while ((line = reader.readLine()) != null)
@@ -217,7 +219,7 @@ label = Name:\\u0020</pre>
// Try to short-circuit when there is no escape char.
int start = pos;
boolean needsEscape = line.indexOf('\\', pos) != -1;
- StringBuilder key = needsEscape ? new StringBuilder() : null;
+ CPStringBuilder key = needsEscape ? new CPStringBuilder() : null;
while (pos < line.length()
&& ! Character.isWhitespace(c = line.charAt(pos++))
&& c != '=' && c != ':')
@@ -361,6 +363,24 @@ label = Name:\\u0020</pre>
}
/**
+ * Reads a property list from the supplied input stream.
+ * This method has the same functionality as {@link #load(Reader)}
+ * but the character encoding is assumed to be ISO-8859-1.
+ * Unicode characters not within the Latin1 set supplied by
+ * ISO-8859-1 should be escaped using '\\uXXXX' where XXXX
+ * is the UTF-16 code unit in hexadecimal.
+ *
+ * @param inStream the byte stream to read the property list from.
+ * @throws IOException if an I/O error occurs.
+ * @see #load(Reader)
+ * @since 1.2
+ */
+ public void load(InputStream inStream) throws IOException
+ {
+ load(new InputStreamReader(inStream, "ISO-8859-1"));
+ }
+
+ /**
* Calls <code>store(OutputStream out, String header)</code> and
* ignores the IOException that may be thrown.
*
@@ -421,7 +441,7 @@ label = Name:\\u0020</pre>
Iterator iter = entrySet ().iterator ();
int i = size ();
- StringBuilder s = new StringBuilder (); // Reuse the same buffer.
+ CPStringBuilder s = new CPStringBuilder (); // Reuse the same buffer.
while (--i >= 0)
{
Map.Entry entry = (Map.Entry) iter.next ();
@@ -564,7 +584,7 @@ label = Name:\\u0020</pre>
* leading spaces must be escaped for the value
* @see #store(OutputStream, String)
*/
- private void formatForOutput(String str, StringBuilder buffer, boolean key)
+ private void formatForOutput(String str, CPStringBuilder buffer, boolean key)
{
if (key)
{
@@ -745,7 +765,7 @@ label = Name:\\u0020</pre>
Boolean.FALSE);
XMLStreamReader reader = factory.createXMLStreamReader(in);
String name, key = null;
- StringBuffer buf = null;
+ CPStringBuilder buf = null;
while (reader.hasNext())
{
switch (reader.next())
@@ -760,7 +780,7 @@ label = Name:\\u0020</pre>
String msg = "missing 'key' attribute";
throw new InvalidPropertiesFormatException(msg);
}
- buf = new StringBuffer();
+ buf = new CPStringBuilder();
}
else if (!"properties".equals(name) && !"comment".equals(name))
{
diff --git a/libjava/classpath/java/util/PropertyResourceBundle.java b/libjava/classpath/java/util/PropertyResourceBundle.java
index 53a1af5360b..b528f08ca85 100644
--- a/libjava/classpath/java/util/PropertyResourceBundle.java
+++ b/libjava/classpath/java/util/PropertyResourceBundle.java
@@ -40,6 +40,7 @@ package java.util;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
/**
* This class is a concrete <code>ResourceBundle</code> that gets it
@@ -97,7 +98,8 @@ public class PropertyResourceBundle extends ResourceBundle
private Properties properties;
/**
- * Creates a new property resource bundle.
+ * Creates a new property resource bundle. The property file must
+ * be encoded using ISO-8859-1.
*
* @param stream an input stream, where the resources are read from
* @throws NullPointerException if stream is null
@@ -110,6 +112,21 @@ public class PropertyResourceBundle extends ResourceBundle
}
/**
+ * Creates a new property resource bundle. The encoding of the property
+ * file is determined by the supplied {@link Reader} object.
+ *
+ * @param reader an input stream, where the resources are read from
+ * @throws NullPointerException if stream is null
+ * @throws IOException if reading the stream fails
+ * @since 1.6
+ */
+ public PropertyResourceBundle(Reader reader) throws IOException
+ {
+ properties = new Properties();
+ properties.load(reader);
+ }
+
+ /**
* Called by <code>getObject</code> when a resource is needed. This
* returns the resource given by the key.
*
diff --git a/libjava/classpath/java/util/ResourceBundle.java b/libjava/classpath/java/util/ResourceBundle.java
index 9b82bc80152..21243403c5f 100644
--- a/libjava/classpath/java/util/ResourceBundle.java
+++ b/libjava/classpath/java/util/ResourceBundle.java
@@ -41,6 +41,8 @@ package java.util;
import gnu.classpath.VMStackWalker;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.IOException;
import java.io.InputStream;
@@ -121,9 +123,10 @@ public abstract class ResourceBundle
*
* @see BundleKey
*/
- private static Map bundleCache = new LinkedHashMap(CACHE_SIZE + 1, 0.75F, true)
+ private static Map<BundleKey,Object> bundleCache =
+ new LinkedHashMap<BundleKey,Object>(CACHE_SIZE + 1, 0.75F, true)
{
- public boolean removeEldestEntry(Map.Entry entry)
+ public boolean removeEldestEntry(Map.Entry<BundleKey,Object> entry)
{
return size() > CACHE_SIZE;
}
@@ -294,14 +297,29 @@ public abstract class ResourceBundle
&& locale.equals(key.locale)
&& classLoader.equals(key.classLoader);
}
+
+ public String toString()
+ {
+ CPStringBuilder builder = new CPStringBuilder(getClass().getName());
+ builder.append("[defaultLocale=");
+ builder.append(defaultLocale);
+ builder.append(",baseName=");
+ builder.append(baseName);
+ builder.append(",locale=");
+ builder.append(locale);
+ builder.append(",classLoader=");
+ builder.append(classLoader);
+ builder.append("]");
+ return builder.toString();
+ }
}
/** A cache lookup key. This avoids having to a new one for every
* getBundle() call. */
- private static BundleKey lookupKey = new BundleKey();
+ private static final BundleKey lookupKey = new BundleKey();
/** Singleton cache entry to represent previous failed lookups. */
- private static Object nullEntry = new Object();
+ private static final Object nullEntry = new Object();
/**
* Get the appropriate ResourceBundle for the given locale. The following
@@ -452,7 +470,7 @@ public abstract class ResourceBundle
ResourceBundle bundle = null;
try
{
- Class rbClass;
+ Class<?> rbClass;
if (classloader == null)
rbClass = Class.forName(localizedName);
else
@@ -495,7 +513,7 @@ public abstract class ResourceBundle
}
/**
- * Tries to load a the bundle for a given locale, also loads the backup
+ * Tries to load the bundle for a given locale, also loads the backup
* locales with the same language.
*
* @param baseName the raw bundle name, without locale qualifiers
@@ -515,9 +533,9 @@ public abstract class ResourceBundle
int baseLen = baseName.length();
- // Build up a StringBuffer containing the complete bundle name, fully
+ // Build up a CPStringBuilder containing the complete bundle name, fully
// qualified by locale.
- StringBuffer sb = new StringBuffer(baseLen + variant.length() + 7);
+ CPStringBuilder sb = new CPStringBuilder(baseLen + variant.length() + 7);
sb.append(baseName);
@@ -568,4 +586,40 @@ public abstract class ResourceBundle
return first;
}
+
+ /**
+ * Remove all resources from the cache that were loaded
+ * using the class loader of the calling class.
+ *
+ * @since 1.6
+ */
+ public static final void clearCache()
+ {
+ clearCache(VMStackWalker.getCallingClassLoader());
+ }
+
+ /**
+ * Remove all resources from the cache that were loaded
+ * using the specified class loader.
+ *
+ * @param loader the loader used for the bundles that will be removed.
+ * @throws NullPointerException if {@code loader} is {@code null}.
+ * @since 1.6
+ */
+ public static final void clearCache(ClassLoader loader)
+ {
+ if (loader == null)
+ throw new NullPointerException("The loader can not be null.");
+ synchronized (ResourceBundle.class)
+ {
+ Iterator<BundleKey> iter = bundleCache.keySet().iterator();
+ while (iter.hasNext())
+ {
+ BundleKey key = iter.next();
+ if (key.classLoader == loader)
+ iter.remove();
+ }
+ }
+ }
+
}
diff --git a/libjava/classpath/java/util/Scanner.java b/libjava/classpath/java/util/Scanner.java
new file mode 100644
index 00000000000..cc39f191de9
--- /dev/null
+++ b/libjava/classpath/java/util/Scanner.java
@@ -0,0 +1,2223 @@
+/* java.util.Scanner -- Parses primitive types and strings using regexps
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.ReadableByteChannel;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.ParseException;
+
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author E0327023 Hernadi Laszlo
+ */
+public class Scanner
+ implements Iterator <String>
+{
+ private static final String NOT_LONG = "\" is not a long"; //$NON-NLS-1$
+
+ private static final String ERR_PREFIX = "\""; //$NON-NLS-1$
+
+ private static final String NOT_INT = "\" is not an integer"; //$NON-NLS-1$
+
+ private static final String NOT_DOUBLE = "\" is not a double"; //$NON-NLS-1$
+
+ private static final String NOT_BYTE = "\" is not a byte"; //$NON-NLS-1$
+
+ private static final String NOT_BOOLEAN = "\" is not a boolean"; //$NON-NLS-1$
+
+ private static final String IS_NOT = "\" is not "; //$NON-NLS-1$
+
+ private static final String DEFAULT_PATTERN_S = "\\p{javaWhitespace}+"; //$NON-NLS-1$
+
+ private static final Pattern DEFAULT_PATTERN =
+ Pattern.compile (DEFAULT_PATTERN_S);
+
+ private static final String BIG_INTEGER = "BigInteger"; //$NON-NLS-1$
+
+ private final static String NEW_LINE =
+ System.getProperty ("line.separator");
+
+ private IOException lastIOException = null;
+
+ /**
+ * An InputStream source if a Constructor with an InputStream source is called, otherwise it
+ * stays <source> null </source>.
+ */
+ private InputStream bIS = null;
+
+ /**
+ * Length of the input Buffer, which is the maximum bytes to be read at once.
+ */
+ private final int MaxBufferLen = 1000000;
+
+ /**
+ * Minimum buffer length. If there are less chars in the Buffer than this value reading from
+ * source is tried.
+ */
+ private final int MIN_BUF_LEN = 100;
+
+ /**
+ * Maximum number of processed chars in the Buffer. If exeeded, all processed chars from the
+ * beginning of the Buffer will be discarded to save space. The bytes left are copyed into a new
+ * Buffer.
+ */
+ private final int MAX_PREFIX = 10000;
+
+ /**
+ * The Buffer which is used by the Matcher to find given patterns. It is filled up when matcher
+ * hits end or <code> MIN_BUF_LEN </code> is reached.
+ */
+ private String actBuffer = new String ();
+
+ /**
+ * The current radix to use by the methods getNextXXX and hasNextXXX.
+ */
+ private int currentRadix = 10;
+
+ /**
+ * The current locale.
+ *
+ * @see #useLocale(Locale)
+ * @see #locale()
+ */
+ private Locale actLocale = Locale.getDefault ();
+
+ /**
+ * The current pattern for the matcher.
+ */
+ private Pattern p = DEFAULT_PATTERN;
+
+ /**
+ * The current position in the Buffer, at which the next match should start.
+ */
+ private int actPos = 0;
+
+ /**
+ * A global buffer to save new allocations by reading from source.
+ */
+ private final byte[] tmpBuffer = new byte[this.MaxBufferLen];
+
+ /**
+ * The charsetName to use with the source.
+ */
+ private String charsetName = null;
+
+ /**
+ * The Matcher which is used.
+ */
+ private Matcher myMatcher = this.p.matcher (this.actBuffer);
+
+ /**
+ * The MatchResult is generated at each match, even if match() isn't called.
+ */
+ private MatchResult actResult = null;
+
+ /**
+ * A Readable source if a Constructor with a Readable source is called, otherwise it stays
+ * <source> null </source>.
+ */
+ private Readable readableSource = null;
+
+ /**
+ * A ReadableByteChannel source if a Constructor with a ReadableByteChannel source is called,
+ * otherwise it stays <source> null </source>.
+ */
+ private ReadableByteChannel rbcSource = null;
+
+ /**
+ * Indicates if the close() method was called.
+ */
+ private boolean isClosed = false;
+
+ /**
+ * For performance reasons the last Found is saved, if a hasNextXXX method was called.
+ */
+ private String lastFound = null;
+
+ private boolean lastFoundPresent = false;
+
+ private int lastNextPos = 0;
+
+ private int lastPatternHash = 0;
+
+ private int last_RegionStart = 0;
+
+ private int last_RegionEnd = 0;
+
+ private boolean last_anchor = false;
+
+ private boolean last_transparent = false;
+
+ private MatchResult lastResult = null;
+
+ /**
+ * To keep track of the current position in the stream for the toString method, each time
+ * processed chars are removed the amount is added to processedChars.
+ */
+ private int procesedChars = 0;
+
+ /**
+ * needInput is set <code> true </code> before a read method, and if there is no input it blocks
+ * and stays <code>true</code>. Right after a read it is set to <code>false</code>.
+ */
+ private boolean needInput = false;
+
+ private boolean skipped = false;
+
+ /**
+ * <code> {@link #doSkipp} </code> indicates that the found pattern belongs to the result. If
+ * <code> {@link #doSkipp} </code> is false the match result ends at the beginning of the match.
+ * In both cases the current position is set after the pattern, if the found pattern has to be
+ * removed, a nextXXX method is called.
+ */
+ private boolean doSkipp = false;
+
+ /**
+ * Indicates if the last match was valid or not.
+ */
+ private boolean matchValid = false;
+
+ private NumberFormat actFormat = NumberFormat.getInstance (this.actLocale);
+
+ private DecimalFormat df = (DecimalFormat) this.actFormat;
+
+ /**
+ * Indicates if current Locale should be used at the input.
+ */
+ private boolean useLocale = true;
+
+ private DecimalFormatSymbols dfs =
+ new DecimalFormatSymbols (this.actLocale);
+
+ /**
+ * Constructs a new Scanner with the given File as source.
+ * {@link #Scanner(InputStream, String)} is called with <code> null </code> as charsetName.
+ *
+ * @param source
+ * The File to use as source.
+ * @throws FileNotFoundException
+ * If the file is not found an Exception is thrown.
+ */
+ public Scanner (final File source) throws FileNotFoundException // TESTED
+ {
+ this (source, null);
+ }
+
+ /**
+ * Constructs a new Scanner with the given File as source. <br>
+ * {@link #Scanner(InputStream, String)} is called with the given charsetName.
+ *
+ * @param source
+ * The File to use as source.
+ * @param charsetName
+ * Current charset name of the file. If charsetName is null it behaves if it was not
+ * set.
+ * @throws FileNotFoundException
+ * If the file is not found an Exception is thrown.
+ */
+ public Scanner (final File source,
+ final String charsetName) throws FileNotFoundException
+ {
+ this (new FileInputStream (source), charsetName);
+ }
+
+ /**
+ * Constructs a new Scanner with the given inputStream. <br>
+ * {@link #Scanner(InputStream, String)} is called with <code> null </code> as charsetName.
+ *
+ * @param source
+ * The InputStream to use as source.
+ */
+ public Scanner (final InputStream source) // TESTED
+ {
+ this (source, null);
+ }
+
+ /**
+ * Constructs a new Scanner with the InputSream and a charsetName. Afterwards the Buffer is
+ * filled.
+ *
+ * @param source
+ * The InputStream to use as source.
+ * @param charsetName
+ * The charsetName to apply on the source's data.
+ */
+ public Scanner (final InputStream source, final String charsetName)
+ {
+ this.bIS = (new BufferedInputStream (source));
+ this.charsetName = charsetName;
+ myFillBuffer ();
+ }
+
+ /**
+ * Constructs a new Scanner with a Readable input as source.
+ *
+ * @param source
+ * The Readable to use as source.
+ */
+ public Scanner (final Readable source)
+ {
+ this.readableSource = source;
+ myFillBuffer ();
+ }
+
+ /**
+ * Constructs a new Scanner with a ReadableByteChannel as
+ * source. Therfore the {@link #Scanner(ReadableByteChannel,
+ * String)} is called with <code> null </code> as charsetName.
+ *
+ * @param source
+ * The ReadableByteChannel to use as source.
+ */
+ public Scanner (final ReadableByteChannel source)
+ {
+ this (source, null);
+ }
+
+ /**
+ * Constructs a new Scanner with a ReadableByteChannel as source and
+ * a given charsetName, which is to be applied on it. <br> It also
+ * initiates the main Buffer.
+ *
+ * @param source
+ * The ReadableByteChannel to use as source.
+ * @param charsetName
+ * The charsetName to be applied on the source.
+ */
+ public Scanner (final ReadableByteChannel source, final String charsetName)
+ {
+ this.charsetName = charsetName;
+ this.rbcSource = source;
+ myFillBuffer ();
+ }
+
+ /**
+ * Constructs a new Scanner using the given String as input only.
+ *
+ * @param source
+ * The whole String to be used as source.
+ */
+ public Scanner (final String source) // TESTED
+ {
+ this.actBuffer = new String (source);
+ this.myMatcher.reset (this.actBuffer);
+ }
+
+ /**
+ * Closes this Scanner. If an {@link IOException} occurs it is
+ * catched and is available under {@link #ioException()}.<br> After
+ * the Scanner is closed, all searches will lead to a {@link
+ * IllegalStateException}.
+ */
+ public void close ()
+ {
+ try
+ {
+ if (this.bIS != null)
+ this.bIS.close ();
+ if (this.rbcSource != null)
+ this.rbcSource.close ();
+ this.isClosed = true;
+ }
+ catch (IOException ioe)
+ {
+ this.lastIOException = ioe;
+ }
+ }
+
+ /**
+ * Returns the current delimiter.
+ *
+ * @return the current delimiter.
+ */
+ public Pattern delimiter () // TESTED
+ {
+ return this.p;
+ }
+
+ /**
+ * Tries to find the pattern in the current line.
+ *
+ * @param pattern The pattern which should be searched in the
+ * current line of the input.
+ * @throws NoSuchElementException
+ * If the pattern was not found.
+ * @return If the search was successful, the result or otherwise a
+ * {@link NoSuchElementException} is thrown.
+ */
+ public String findInLine (final Pattern pattern) throws NoSuchElementException // TESTED
+ {
+ String tmpStr = myNextLine (false);
+ return myFindPInStr (pattern, tmpStr, 0);
+ }
+
+ /**
+ * Compiles the given pattern into a {@link Pattern} and calls
+ * {@link #findInLine(Pattern)} with the compiled pattern and
+ * returns whatever it returns.
+ *
+ * @param pattern
+ * The pattern which should be matched in the input.
+ * @throws NoSuchElementException
+ * If the pattern was not found.
+ * @return The match in the current line.
+ */
+ public String findInLine (final String pattern) // TESTED
+ {
+ return findInLine (Pattern.compile (pattern));
+ }
+
+ /**
+ * Trys to match the pattern within the given horizon.
+ *
+ * @param pattern
+ * Pattern to search.
+ * @param horizon
+ * @return The result of the match.
+ * @throws IllegalArgumentException
+ * if the horizon is negative.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public String findWithinHorizon (final Pattern pattern, final int horizon)
+ throws IllegalArgumentException, IllegalStateException
+ {
+ if (horizon < 0)
+ {
+ throw new IllegalArgumentException (horizon + " is negative");
+ }
+
+ if (this.isClosed)
+ {
+ throw new IllegalStateException ("Scanner is closed");
+ }
+
+ // doSkipp is set true to get the matching patern together with the found String
+ this.doSkipp = true;
+ String rc = myFindPInStr (pattern, this.actBuffer, horizon);
+
+ if (rc != null)
+ {
+ this.actPos += rc.length ();
+ }
+
+ return rc;
+ }
+
+ /**
+ * Compile the pattern and call {@link #findWithinHorizon(Pattern,
+ * int)}.
+ *
+ * @param pattern
+ * Pattern to search.
+ * @param horizon
+ * @return The result of the match.
+ * @throws IllegalArgumentException
+ * if the horizon is negative.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public String findWithinHorizon (final String pattern, final int horizon)
+ throws IllegalArgumentException, IllegalStateException
+ {
+ return findWithinHorizon (Pattern.compile (pattern), horizon);
+ }
+
+ /**
+ * Checks if there is any next String using the current
+ * delimiter. Therefore the string must not be <code> null </code>
+ * and the length must be greater then 0. If a {@link
+ * NoSuchElementException} is thrown by the search method, it is
+ * catched and false is returned.
+ *
+ * @return <code> true </code> if there is any result using the current delimiter. This wouldn't
+ * lead to a {@link NoSuchElementException}.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNext () throws IllegalStateException // TESTED
+ {
+ String tmpStr = null;
+
+ try
+ {
+ tmpStr = myCoreNext (false, this.p);
+ }
+ catch (NoSuchElementException nf)
+ {
+ }
+
+ if (tmpStr == null || tmpStr.length () <= 0)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Searches the pattern in the next subString before the next
+ * current delimiter.
+ *
+ * @param pattern
+ * The pattern to search for.
+ * @return <code> true </code> if the pattern is found before the current delimiter.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNext (final Pattern pattern) throws IllegalStateException // TESTED
+ {
+ String tmpStr;
+
+ tmpStr = myNext (pattern, false);
+
+ if (tmpStr == null || tmpStr.length () <= 0)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compiles the pattern to a {@link Pattern} and calls {@link
+ * #hasNext(Pattern)}.
+ *
+ * @see #hasNext(Pattern)
+ * @param pattern
+ * The pattern as string to search for.
+ * @return <code> true </code> if the pattern is found before the current delimiter.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNext (final String pattern) throws IllegalStateException // TESTED
+ {
+ return hasNext (Pattern.compile (pattern));
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a BigDecimal number. <br> BigDecimal numbers are always tryed
+ * with radix 10.
+ *
+ * @see #nextBigDecimal()
+ * @return <code> true </code> if the next string is a BigDecimal number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextBigDecimal () throws IllegalStateException // TESTED
+ {
+ try
+ {
+ myBigDecimal (false);
+ return true;
+ }
+ catch (InputMismatchException nfe)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a BigInteger number. <br> Call {@link #hasNextBigInteger(int)}
+ * with the current radix.
+ *
+ * @see #nextBigInteger()
+ * @return <code> true </code> if the next string is a BigInteger number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextBigInteger () throws IllegalStateException // TESTED
+ {
+ return hasNextBigInteger (this.currentRadix);
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a BigInteger number. <br>
+ *
+ * @param radix
+ * The radix to use for this check. The global radix of the Scanner will not be
+ * changed.
+ * @return <code> true </code> if the next string is a BigInteger number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextBigInteger (final int radix) throws
+ IllegalStateException
+ {
+ try
+ {
+ myNextBigInteger (radix, false, BIG_INTEGER);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the next string could be a boolean. The method handles
+ * the input not case sensitiv, so "true" and "TRUE" and even "tRuE"
+ * are <code> true </code>.
+ *
+ * @see #nextBoolean()
+ * @return Return <code> true </code> if the next string is a boolean.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextBoolean () throws IllegalStateException // TESTED
+ {
+ try
+ {
+ myNextBoolean (false);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a byte number. <br> Calls {@link #hasNextByte(int)} with the
+ * current radix.
+ *
+ * @see #nextByte()
+ * @return <code> true </code> if the next string is a byte number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextByte () throws IllegalStateException // TESTED
+ {
+ return hasNextByte (this.currentRadix);
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a byte number with the given radix. <br> To check, the private
+ * method {@link #myNextByte(int, boolean)} is called, and if no
+ * error occurs the next string could be a byte.
+ *
+ * @see #nextByte(int)
+ * @param radix The radix to use for this check. The global radix of
+ * the Scanner will not be changed.
+ * @return <code> true </code> if the next string is a byte number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextByte (final int radix) throws IllegalStateException
+ {
+ try
+ {
+ myNextByte (radix, false);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a double number. <br> To check, the private method {@link
+ * #myNextDouble(boolean)} is called, and if no error occurs the
+ * next string could be a double.
+ *
+ * @see #nextDouble()
+ * @return <code> true </code> if the next string is a double number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextDouble () throws IllegalStateException // TESTED
+ {
+ try
+ {
+ myNextDouble (false);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a double number. Because every float is a double this is
+ * checked.<br> To check, the private method {@link
+ * #myNextDouble(boolean)} is called, and if no error occurs the
+ * next string could be a double.
+ *
+ * @see #nextFloat()
+ * @return <code> true </code> if the next string is a double number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextFloat () throws IllegalStateException // TESTED
+ {
+ try
+ {
+ myNextDouble (false);
+ // myNextFloat(false);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * an int number. <br> To check, the private method {@link
+ * #myNextInt(int, boolean)} is called, and if no error occurs the
+ * next string could be an int.
+ *
+ * @see #nextInt(int)
+ * @return <code> true </code> if the next string is an int number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextInt () throws IllegalStateException // TESTED
+ {
+ return hasNextInt (this.currentRadix);
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * an int number with the given radix. <br> To check, the private
+ * method {@link #myNextInt(int, boolean)} is called, and if no
+ * error occurs the next string could be an int.
+ *
+ * @see #nextInt(int)
+ * @param radix
+ * The radix to use for this check. The global radix of the Scanner will not be
+ * changed.
+ * @return <code> true </code> if the next string is an int number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextInt (final int radix) throws IllegalStateException
+ {
+ try
+ {
+ myNextInt (radix, false);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if there is a current line, which ends at the next line
+ * break or the end of the input.
+ *
+ * @return <code> true </code> if there is a current line.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextLine () throws IllegalStateException // TESTED
+ {
+ return (myNextLine (false) != null);
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a long number. <br> To check, the private method {@link
+ * #myNextLong(int, boolean)} is called, and if no error occurs the
+ * next string could be a long.
+ *
+ * @see #nextLong()
+ * @return <code> true </code> if the next string is a long number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextLong () throws IllegalStateException // TESTED
+ {
+ return hasNextLong (this.currentRadix);
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a long number with the given radix. <br> To check, the private
+ * method {@link #myNextLong(int, boolean)} is called, and if no
+ * error occurs the next string could be a long.
+ *
+ * @see #nextLong(int)
+ * @param radix
+ * The radix to use for this check. The global radix of the Scanner will not be
+ * changed.
+ * @return <code> true </code> if the next string is a long number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextLong (final int radix) throws IllegalStateException
+ {
+ try
+ {
+ myNextLong (radix, false);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a short number with the given radix. <br> To check, the private
+ * method {@link #myNextShort(int, boolean)} is called, and if no
+ * error occurs the next string could be a short.
+ *
+ * @see #nextShort(int)
+ * @return <code> true </code> if the next string is a short number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextShort () throws IllegalStateException // TESTED
+ {
+ return hasNextShort (this.currentRadix);
+ }
+
+ /**
+ * Checks if the string to the next delimiter can be interpreted as
+ * a short number. <br> To check, the private method {@link
+ * #myNextShort(int, boolean)} is called, and if no error occurs the
+ * next string could be a short.
+ *
+ * @see #nextShort(int)
+ * @param radix
+ * The radix to use for this check. The global radix of the Scanner will not be
+ * changed.
+ * @return <code> true </code> if the next string is a short number.
+ * @throws IllegalStateException
+ * if the Scanner is closed.
+ */
+ public boolean hasNextShort (final int radix) throws IllegalStateException
+ {
+ try
+ {
+ myNextShort (radix, false);
+ return true;
+ }
+ catch (InputMismatchException ime)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the last {@link IOException} occured.
+ *
+ * @return Returns the last {@link IOException}.
+ */
+ public IOException ioException ()
+ {
+ return this.lastIOException;
+ }
+
+ /**
+ * Returns the current value of {@link #useLocale}. This is used to
+ * tell the Scanner if it should use the Locale format or just
+ * handle numbers of the default format.
+ *
+ * @see #setUseLocale(boolean)
+ * @return the useLoclae.
+ */
+ public boolean isUseLocale () // TESTED
+ {
+ return this.useLocale;
+ }
+
+ /**
+ * Returns the current Locale. It is initialized with {@link
+ * Locale#getDefault()}.
+ *
+ * @see #useLocale(Locale)
+ * @return Returns the current Locale.
+ */
+ public Locale locale () // TESTED
+ {
+ return this.actLocale;
+ }
+
+ /**
+ * Returns the last MatchResult found. This is updated after every
+ * successfully search.
+ *
+ * @return Returns the last {@link MatchResult} found.
+ */
+ public MatchResult match () // TESTED
+ {
+ return this.actResult;
+ }
+
+ /**
+ * Uses the current delimiter to find the next string in the
+ * buffer. If a string is found the current position is set after
+ * the delimiter, otherwise a {@link NoSuchElementException} is
+ * thrown. A successful match sets the matchResult.
+ *
+ * @see #match()
+ * @return Returns the next string of the buffer.
+ * @throws NoSuchElementException
+ * If no element was found an exception is thrown.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public String next () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return myCoreNext (true, this.p);
+ }
+
+ /**
+ * Tries to match the buffer with the given pattern. The current
+ * delimiter will not be changed.
+ *
+ * @param pattern
+ * The pattern to match.
+ * @return Returns the next string matching the pattern.
+ * @throws NoSuchElementException
+ * If no element was found an exception is thrown.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public String next (final Pattern pattern) throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return myNext (pattern, true);
+ }
+
+ /**
+ * Tries to match the buffer with the given pattern. The current
+ * delimiter will not be changed. Calls the {@link #next(Pattern)}
+ * with the compiled pattern.
+ *
+ * @see #next(Pattern)
+ * @param pattern
+ * The pattern to match.
+ * @return Returns the next string matching the pattern.
+ * @throws NoSuchElementException
+ * If no element was found an exception is thrown.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public String next (final String pattern) throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return next (Pattern.compile (pattern));
+ }
+
+ /**
+ * Tries to interpret the next string as a BigDecimal value.
+ *
+ * @return Returns the BigDecimal value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a BigDecimal.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public BigDecimal nextBigDecimal () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return myBigDecimal (true);
+ }
+
+ /**
+ * Tries to interpret the next string as a BigInteger value. Call
+ * {@link #nextBigInteger(int)} with the current radix as parameter,
+ * and return the value.
+ *
+ * @see #nextBigInteger(int)
+ * @return Returns the BigInteger value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a BigInteger.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public BigInteger nextBigInteger () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return nextBigInteger (this.currentRadix);
+ }
+
+ /**
+ * Tries to interpret the next string as a BigInteger value with the
+ * given radix.
+ *
+ * @param radix
+ * The radix to be used for this BigInteger. The current radix of the Scanner is not
+ * changed.
+ * @return Returns the BigInteger value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a BigInteger.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public BigInteger nextBigInteger (final int radix) throws
+ NoSuchElementException, IllegalStateException
+ {
+ return myNextBigInteger (radix, true, BIG_INTEGER);
+ }
+
+ /**
+ * Tries to interpret the next string to the delimiter as a boolean
+ * value, ignoring case.
+ *
+ * @return Returns the boolean value of the next matching string or throws an exception.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a boolean.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public boolean nextBoolean () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return myNextBoolean (true);
+ }
+
+ /**
+ * Tries to interpret the next string as a byte value. Call {@link
+ * #nextByte(int)} with the current radix as parameter, and return
+ * the value.
+ *
+ * @see #nextByte(int)
+ * @return Returns the byte value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a byte
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public byte nextByte () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return nextByte (this.currentRadix);
+ }
+
+ /**
+ * Tries to interpret the next string as a byte value with the given
+ * radix.
+ *
+ * @param radix
+ * The radix to be used for this byte. The current radix of the Scanner is not
+ * changed.
+ * @return Returns the byte value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a byte.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public byte nextByte (final int radix) throws NoSuchElementException,
+ IllegalStateException
+ {
+ return myNextByte (radix, true);
+ }
+
+ /**
+ * Tries to interpret the next string as a double value.
+ *
+ * @return Returns the int value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a double.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public double nextDouble () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return myNextDouble (true);
+ }
+
+ /**
+ * Tries to interpret the next string as a double value, and then
+ * casts down to float.
+ *
+ * @return Returns the int value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a double.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public float nextFloat () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return (float) myNextDouble (true);
+ // return myNextFloat(true);
+ }
+
+ /**
+ * Tries to interpret the next string as an int value. Calls {@link
+ * #nextInt(int)} with the current radix as parameter, and return
+ * the value.
+ *
+ * @see #nextInt(int)
+ * @return Returns the int value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not an int.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public int nextInt () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return nextInt (this.currentRadix);
+ }
+
+ /**
+ * Tries to interpret the next string as an int value with the given
+ * radix.
+ *
+ * @param radix
+ * The radix to be used for this int. The current radix of the Scanner is not changed
+ * @return Returns the int value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not an int.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public int nextInt (final int radix) throws NoSuchElementException,
+ IllegalStateException
+ {
+ return myNextInt (radix, true);
+ }
+
+ /**
+ * Tries to match the system line seperator, and returns the current
+ * line.
+ *
+ * @return Returns the current line.
+ * @throws NoSuchElementException
+ * If the current delimiter is not found.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public String nextLine () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return myNextLine (true);
+ }
+
+ /**
+ * Tries to interpret the next string as a long value. Calls {@link
+ * #nextLong(int)} with the current radix as parameter, and return
+ * the value.
+ *
+ * @see #nextLong(int)
+ * @return Returns the long value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a long.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public long nextLong () throws NoSuchElementException, IllegalStateException // TESTED
+ {
+ return nextLong (this.currentRadix);
+ }
+
+ /**
+ * Tries to interpret the next string as a long value with the given
+ * radix.
+ *
+ * @param radix
+ * The radix to be used for this long. The current radix of the Scanner is not
+ * changed
+ * @return Returns the long value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a long.
+ * @throws IllegalStateException
+ * If the Scanner is closed.
+ */
+ public long nextLong (final int radix) throws NoSuchElementException,
+ IllegalStateException
+ {
+ return myNextLong (radix, true);
+ }
+
+ /**
+ * Tries to interpret the next string as a short value. Calls {@link
+ * #nextShort(int)} with the current radix as parameter, and return
+ * the value.
+ *
+ * @see #nextShort(int)
+ * @return Returns the short value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a short.
+ */
+ public short nextShort () throws NoSuchElementException // TESTED
+ {
+ return nextShort (this.currentRadix);
+ }
+
+ /**
+ * Tries to interpret the next string as a short value with the
+ * given radix.
+ *
+ * @param radix
+ * The radix to be used for this short. The current radix of the Scanner is not
+ * changed.
+ * @return Returns the short value of the next string.
+ * @throws NoSuchElementException
+ * If no string is found or the string is not a short.
+ */
+ public short nextShort (final int radix) throws NoSuchElementException
+ {
+ return myNextShort (radix, true);
+ }
+
+ /**
+ * @return Returns the current radix.
+ */
+ public int radix ()
+ {
+ return this.currentRadix;
+ }
+
+ /**
+ * The remove operation is not supported by this implementation of
+ * Iterator.
+ */
+ public void remove ()
+ {
+ }
+
+ /**
+ * @param useLocale the useLocale to set.
+ */
+ public void setUseLocale (final boolean useLocale) // TESTED
+ {
+ this.useLocale = useLocale;
+ }
+
+ /**
+ * Skips the given pattern. Sets skipped <code>true</code>.
+ *
+ * @param pattern
+ * Pattern which should be skipped.
+ * @return <code>this</code> with the skipped buffer.
+ * @throws NoSuchElementException
+ * If the Pattern is not found.
+ */
+ public Scanner skip (final Pattern pattern) throws NoSuchElementException
+ {
+ this.doSkipp = true;
+ int end;
+ boolean found;
+ Matcher matcher = pattern.matcher (this.actBuffer);
+ matcher.region (this.actPos - 1, this.actBuffer.length ());
+
+ found = matcher.find ();
+ found = myFillBuffer_loop (matcher, this.actPos - 1, found);
+ end = matcher.end ();
+
+ this.actPos = end + 1;
+
+ this.doSkipp = false;
+ this.skipped = true;
+
+ actResult = null;
+
+ if (!found)
+ {
+ throw new NoSuchElementException ();
+ }
+ return this;
+ }
+
+ /**
+ * Skips a given pattern. Calls {@link #skip(Pattern)} with the
+ * compiled pattern.
+ *
+ * @see #skip(Pattern)
+ * @param pattern
+ * Pattern which should be skipped.
+ * @return <code>this</code> with the skipped buffer.
+ */
+ public Scanner skip (final String pattern)
+ {
+ return skip (Pattern.compile (pattern));
+ }
+
+ /**
+ * Returns the string representation of this Scanner.
+ */
+ @Override
+ public String toString ()
+ {
+ String tmpStr2;
+ String rc = this.getClass ().getName ();
+ tmpStr2 = rc;
+ tmpStr2 = "[delimiters=" + this.p.pattern () + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[position=" + (this.procesedChars + this.actPos) + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[match valid=" + this.matchValid + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[need input=" + this.needInput + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[source closed=" + this.isClosed + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[skipped=" + this.skipped + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[group separator=\\" + this.dfs.getGroupingSeparator () + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[decimal separator=\\" + this.dfs.getDecimalSeparator () + "]";
+ rc += tmpStr2;
+ tmpStr2 =
+ "[positive prefix=" + myConvert (this.df.getPositivePrefix ()) + "]";
+ rc += tmpStr2;
+ tmpStr2 =
+ "[negative prefix=" + myConvert (this.df.getNegativePrefix ()) + "]";
+ rc += tmpStr2;
+ tmpStr2 =
+ "[positive suffix=" + myConvert (this.df.getPositiveSuffix ()) + "]";
+ rc += tmpStr2;
+ tmpStr2 =
+ "[negative suffix=" + myConvert (this.df.getNegativeSuffix ()) + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[NaN string=" + myConvert (this.dfs.getNaN ()) + "]";
+ rc += tmpStr2;
+ tmpStr2 = "[infinity string=" + myConvert (this.dfs.getInfinity ()) + "]";
+ rc += tmpStr2;
+ return rc;
+ }
+
+ /**
+ * Sets the current pattern to the given parameter, and updates the
+ * {@link Matcher} with the new pattern.
+ *
+ * @param pattern
+ * The new pattern to use.
+ * @return Returns the Scanner (<code>this</code>) with the new pattern.
+ */
+ public Scanner useDelimiter (final Pattern pattern) // TESTED
+ {
+ if (pattern != null)
+ {
+ this.p = pattern;
+ this.myMatcher = this.p.matcher (this.actBuffer);
+ }
+ return this;
+ }
+
+ /**
+ * Sets the current pattern to the given parameter. Compiles the
+ * pattern and calls {@link #useDelimiter(Pattern)}
+ *
+ * @see #useDelimiter(Pattern)
+ * @param pattern
+ * The new pattern to use.
+ * @return Returns the Scanner (<code>this</code>) with the new pattern.
+ */
+ public Scanner useDelimiter (final String pattern) // TESTED
+ {
+ return useDelimiter (Pattern.compile (pattern));
+ }
+
+ /**
+ * Sets the current Locale to the given parameter. Formats and
+ * Symbols are also set using the new Locale.
+ *
+ * @param locale The new Locale to use. If it is <code>null</code>
+ * nothing happens.
+ * @return Returns the Scanner (<code>this</code>) with the new Locale.
+ */
+ public Scanner useLocale (final Locale locale) // TESTED
+ {
+ if (locale != null)
+ {
+ this.actLocale = locale;
+ this.actFormat = NumberFormat.getInstance (this.actLocale);
+ this.dfs = new DecimalFormatSymbols (this.actLocale);
+ this.df = (DecimalFormat) this.actFormat;
+ }
+ return this;
+ }
+
+ /**
+ * Sets the current radix to the current value if the given radix is
+ * >= 2 and <= 36 otherwise an {@link IllegalArgumentException} is
+ * thrown.
+ *
+ * @param radix
+ * the new radix to use as default.
+ * @return <code> this </code> with the new radix value.
+ * @throws IllegalArgumentException
+ * When the given radix is out of bounds.
+ */
+ public Scanner useRadix (final int radix) throws IllegalArgumentException
+ {
+ if (radix < 2 || radix > 36)
+ {
+ throw new IllegalArgumentException ();
+ }
+ this.currentRadix = radix;
+ return this;
+ }
+
+ /**
+ * Checks if it is necessary to apply the current Locale on the
+ * String. If so the String is converted using the {@link
+ * NumberFormat#parse(String)} into a Number and then back to a
+ * default stringrepresentation of that Number.
+ *
+ * @see #setUseLocale(boolean)
+ * @param str
+ * String to convert into another string.
+ * @param radix Radix of the Number in the original string. It has
+ * to be 10 for anything to happen.
+ * @return Eighter the Stringrepresention of the number without the
+ * Locale or an unchanged string.
+ * @throws ParseException
+ * if {@link NumberFormat#parse(String)} fails to parse.
+ */
+ private String myApplyLocale (final String str,
+ final int radix) throws ParseException
+ {
+ String rc;
+
+ if (this.useLocale && radix == 10)
+ {
+ rc = this.actFormat.parse (str).toString ();
+ return rc;
+ }
+
+ return str;
+ }
+
+ /**
+ * If {@link #useLocale} is set and radix is 10 the string is tryed
+ * to be converted to string without Locale settings, because the
+ * "normal" convert from Local has only double precision and it is
+ * not enough for the about 50 digits of precision of the
+ * BigDecimal. So in the first step the string is seperated into the
+ * integer part which is converted to a long, and the fraction part
+ * is appended afterwards. Between the integer and the fraction part
+ * comes a ".". Finally the resulting string is returned.
+ *
+ * @see #setUseLocale(boolean)
+ * @param str String representation of a BigDecimal number.
+ * @return The default String representation (without Locale) of the
+ * BigInteger.
+ * @throws ParseException
+ * If the String has more than one decimal seperators a parse exception is thrown.
+ */
+ private String myApplyLocaleBD (final String str) throws ParseException
+ {
+ if (!this.useLocale || this.currentRadix != 10)
+ {
+ return str;
+ }
+
+ String negPrefix = this.df.getNegativePrefix ();
+ String negSuffix = this.df.getNegativeSuffix ();
+ String posPrefix = this.df.getPositivePrefix ();
+ String posSuffix = this.df.getPositiveSuffix ();
+
+ char d = this.dfs.getDecimalSeparator ();
+ int begin1, begin2;
+ boolean isNegativ = false;
+ String parts = null;
+
+ String tmpStr1 = "";
+
+ begin1 = str.indexOf (d);
+ begin2 = str.indexOf (d, begin1 + 1);
+
+ if (begin2 > 0)
+ {
+ throw new ParseException ("more than one Decimal seperators", begin2);
+ }
+
+ parts = str.substring (0, begin1);
+
+ if ((negPrefix.length () > 0
+ && str.substring (0, negPrefix.length ()).equals (negPrefix))
+ || (negSuffix.length () > 0
+ && str.substring (str.length () -
+ negSuffix.length ()).equals (negSuffix)))
+ {
+ parts += negSuffix;
+ isNegativ = true;
+ }
+ else
+ if ((posPrefix.length () > 0
+ && str.substring (0, posPrefix.length ()).equals (posPrefix))
+ || (posSuffix.length () > 0
+ && str.substring (str.length () -
+ posSuffix.length ()).equals (posSuffix)))
+ {
+ parts += posSuffix;
+ }
+
+ tmpStr1 = this.actFormat.parse (parts).toString ();
+
+ if (isNegativ)
+ {
+ tmpStr1 +=
+ "." + str.substring (str.indexOf (d) + 1,
+ str.length () - negSuffix.length ());
+ }
+ else
+ {
+ tmpStr1 +=
+ "." + str.substring (str.indexOf (d) + 1,
+ str.length () - posSuffix.length ());
+ }
+
+ return tmpStr1;
+ }
+
+ /**
+ * Tries to interpret the next String as a BigDecimal. Therfore the
+ * next String is get with {@link #myCoreNext(boolean, Pattern)} and
+ * then {@link #myApplyLocaleBD(String)} is called to convert the
+ * String into a BigDecimal.
+ *
+ * @param delete
+ * Should the found string be deleted or not.
+ * @return Returns the BigDecimal value of the next string.
+ * @throws InputMismatchException
+ * If the string is not a BigDecimal
+ */
+ private BigDecimal myBigDecimal (final boolean delete) throws
+ InputMismatchException
+ {
+ BigDecimal rc;
+ String tmp = myCoreNext (delete, this.p);
+ try
+ {
+ tmp = myApplyLocaleBD (tmp);
+ }
+ catch (ParseException e)
+ {
+ throw new InputMismatchException (ERR_PREFIX + tmp + IS_NOT +
+ "BigDecimal!!");
+ }
+ rc = new BigDecimal (tmp);
+
+ return rc;
+ }
+
+ /**
+ * Applies suffix ("\E") and prefix ("\Q") if str.length != 0 Used
+ * by the toString method.
+ *
+ * @param str
+ * the string on which the suffix and prefix should be applied.
+ * @return The new new string with the suffix and prefix.
+ */
+ private String myConvert (final String str)
+ {
+ if (str != null && str.length () > 0)
+ {
+ return "\\Q" + str + "\\E";
+ }
+ return str;
+ }
+
+ /**
+ * Searches the current Matcher for the current Pattern. If the end
+ * is reached during the search it tried to read again from the
+ * source. The search results are always saved in {@link #actResult}
+ * which is returned when match() is called. If doSkip is true the
+ * pattern is also taken.
+ *
+ * @param delete
+ * if true the aktPos is set.
+ * @param pattern
+ * pattern to search for.
+ * @return Returns the String which matches the pattern.
+ * @throws NoSuchElementException
+ * If the search has no result.
+ */
+ private String myCoreNext (final boolean delete, final Pattern pattern)
+ throws NoSuchElementException
+ {
+ if (this.isClosed)
+ {
+ throw new IllegalStateException ("Scanner closed");
+ }
+ if (shallUseLastFound (pattern != null ? pattern : this.p))
+ {
+ if (this.last_RegionEnd != this.myMatcher.regionEnd ())
+ {
+ System.out.println (this.last_RegionEnd + " != " +
+ this.myMatcher.regionEnd () + " (" +
+ (this.last_RegionEnd -
+ this.myMatcher.regionEnd ()) + ")");
+ }
+ if (delete)
+ {
+ this.actPos = this.lastNextPos;
+ this.lastFoundPresent = false;
+ this.actResult = this.lastResult;
+ }
+ return this.lastFound;
+ }
+
+ boolean found = false;
+ int left;
+ int endIndex;
+
+ String tmp2 = null;
+
+ if (this.actPos > this.MAX_PREFIX)
+ {
+ // skipp the processed chars so that the size of the buffer don't grow to much even with
+ // huge files
+ this.procesedChars += this.actPos;
+ this.actBuffer = this.actBuffer.substring (this.actPos);
+ this.actPos = 0;
+ this.myMatcher = pattern.matcher (this.actBuffer);
+ }
+
+ left = this.actBuffer.length () - this.actPos;
+ if (left < this.MIN_BUF_LEN)
+ {
+ myFillBuffer ();
+ }
+ found = this.myMatcher.find (this.actPos);
+
+ found = myFillBuffer_loop (this.myMatcher, this.actPos, found);
+
+ this.needInput = false;
+
+ if (found)
+ {
+ if (this.doSkipp)
+ {
+ endIndex = this.myMatcher.end ();
+ }
+ else
+ {
+ endIndex = this.myMatcher.start ();
+ }
+ tmp2 = this.actBuffer.substring (this.actPos, endIndex);
+ this.lastNextPos = this.myMatcher.end ();
+ /*
+ * if the delete flag is set, just set the current position after the end of the matched
+ * pattern.
+ */
+ if (delete)
+ {
+ this.actPos = this.lastNextPos;
+ }
+ else
+ {
+ this.lastFound = tmp2;
+ this.lastFoundPresent = true;
+ this.lastPatternHash = pattern.hashCode ();
+ }
+ this.last_RegionStart = this.myMatcher.regionStart ();
+ this.last_RegionEnd = this.myMatcher.regionEnd ();
+ this.last_anchor = this.myMatcher.hasAnchoringBounds ();
+ this.last_transparent = this.myMatcher.hasTransparentBounds ();
+ }
+ else if (this.myMatcher.hitEnd ())
+ // the end of input is matched
+ {
+ tmp2 = this.actBuffer.substring (this.actPos);
+ this.lastNextPos = this.actBuffer.length ();
+ if (delete)
+ {
+ this.actPos = this.lastNextPos;
+ }
+ else
+ {
+ this.lastFound = tmp2;
+ this.lastFoundPresent = true;
+ this.lastPatternHash = pattern.hashCode ();
+ }
+ this.last_RegionStart = this.myMatcher.regionStart ();
+ this.last_RegionEnd = this.myMatcher.regionEnd ();
+ this.last_anchor = this.myMatcher.hasAnchoringBounds ();
+ this.last_transparent = this.myMatcher.hasTransparentBounds ();
+ }
+ else
+ {
+ /*
+ * if no match found an Exception is throwed
+ */
+ throw new NoSuchElementException ();
+ }
+ /*
+ * change the Result only when a nextXXX() method was called, not if a hasNextXXX() method
+ * is called
+ */
+ if (delete)
+ {
+ this.actResult = this.myMatcher.toMatchResult ();
+
+ this.matchValid = this.actResult != null;
+ }
+ else
+ {
+ this.lastResult = this.myMatcher.toMatchResult ();
+ }
+
+ this.skipped = this.doSkipp;
+ this.doSkipp = false;
+
+ return tmp2;
+ }
+
+ /**
+ * Used to fill the String buffer from a source. Therfore the 3
+ * possible sources are checked if they are not <code>null</code>
+ * and this not used, otherwise the read method is called on the
+ * source. If a charsetName is set and not <code>null</code> it is
+ * applied to convert to String.
+ */
+ private void myFillBuffer ()
+ {
+ int len;
+ String tmpStr;
+ CharBuffer cb = null;
+ ByteBuffer bb = null;
+
+ if (this.bIS != null)
+ {
+ try
+ {
+ len = this.bIS.read (this.tmpBuffer);
+ if (len < 0)
+ {
+ return;
+ }
+ if (this.charsetName != null)
+ {
+ tmpStr = new String (this.tmpBuffer, 0, len, this.charsetName);
+ }
+ else
+ {
+ tmpStr = new String (this.tmpBuffer, 0, len);
+ }
+ this.actBuffer += tmpStr;
+ }
+ catch (IOException e)
+ {
+ this.lastIOException = e;
+ }
+ }
+ else if (this.readableSource != null)
+ {
+ try
+ {
+ cb = CharBuffer.allocate (1000);
+ this.needInput = true;
+ len = this.readableSource.read (cb);
+ if (len < 0)
+ {
+ return;
+ }
+ this.needInput = false;
+ tmpStr = new String (cb.array ());
+ this.actBuffer += tmpStr;
+ }
+ catch (IOException e)
+ {
+ this.lastIOException = e;
+ }
+ }
+ else if (this.rbcSource != null)
+ {
+ try
+ {
+ bb = ByteBuffer.allocate (1000);
+ this.needInput = true;
+ len = this.rbcSource.read (bb);
+ this.needInput = false;
+ if (len < 0)
+ {
+ return;
+ }
+ if (this.charsetName != null)
+ {
+ tmpStr = new String (bb.array (), 0, len, this.charsetName);
+ }
+ else
+ {
+ tmpStr = new String (bb.array (), 0, len);
+ }
+ this.actBuffer += tmpStr;
+ }
+ catch (IOException e)
+ {
+ this.lastIOException = e;
+ }
+ }
+
+ this.myMatcher.reset (this.actBuffer);
+ }
+
+ /**
+ * A loop in which the {@link #myFillBuffer()} is called and checked
+ * if the pattern is found in the matcher and if the buffersize
+ * changes after the read.
+ *
+ * @param aktM
+ * The current Matcher.
+ * @param pos
+ * Position from which the matcher should start matching.
+ * @param found
+ * if already found.
+ * @return <code> true </code> if the matcher has found a match.
+ */
+ private boolean myFillBuffer_loop (final Matcher aktM, final int pos,
+ boolean found)
+ {
+ int tmp;
+
+ tmp = this.actBuffer.length ();
+ while (aktM.hitEnd ()
+ && ((this.bIS != null) || (this.readableSource != null)
+ || (this.rbcSource != null)))
+ {
+ myFillBuffer ();
+ if (tmp == this.actBuffer.length ())
+ {
+ break;
+ }
+ found = aktM.find (pos);
+ this.needInput = true;
+ }
+ return found;
+ }
+
+ /**
+ * Used to find the given pattern in the given string before the
+ * given horizon. Therfore the current matcher is copied, and
+ * overwritten using the given pattern and the given Sting. <br>
+ * After the search the original values are restored, and skipped is
+ * set <code> true </code>.
+ *
+ * @param pattern
+ * Pattern which should be matched.
+ * @param str
+ * The String in which the pattern should be matched.
+ * @param horizon
+ * the horizon whithin the match should be, if 0 then it is ignored.
+ * @return Returns the String in the given String that matches the pattern.
+ */
+ private String myFindPInStr (final Pattern pattern, final String str,
+ final int horizon)
+ {
+ String rc = null;
+ int curPos = this.actPos;
+ Matcher aktMatcher = this.myMatcher;
+
+ this.myMatcher = pattern.matcher (str);
+ if (horizon > 0)
+ {
+ this.myMatcher.useAnchoringBounds (true);
+ this.myMatcher.useTransparentBounds (true);
+ this.myMatcher.region (this.actPos, this.actPos + horizon);
+ }
+ rc = myCoreNext (true, pattern);
+ this.myMatcher = aktMatcher;
+
+ this.actPos = curPos;
+ this.skipped = true;
+
+ return rc;
+ }
+
+ /**
+ * Used by the {@link #hasNext(Pattern)} and {@link #next(Pattern)}
+ * methods. Therfore a substring is taken first to the current
+ * delimiter, afterwards the given pattern is searched in this
+ * subsring.<br> Finally the current Buffer and matcher (which have
+ * been temporarily changed) are set back.<br> <br> The {@link
+ * #skipped} is set <code> true </code>.
+ *
+ * @param pattern
+ * Pattern to find until the current delimiter.
+ * @param delete
+ * Is <code> true </code> if a next method is called.<br>
+ * Is <code> false </code> if a hasNext method is called.
+ * @return Returns the String which is returned by the public methods.
+ */
+ private String myNext (final Pattern pattern, final boolean delete)
+ {
+ String tmpStr;
+ Matcher aktMatcher = this.myMatcher;
+ String result;
+ String currBuffer = this.actBuffer;
+ int currAktPos;
+
+ tmpStr = myCoreNext (delete, this.p);
+ this.myMatcher = pattern.matcher (tmpStr);
+ this.actBuffer = tmpStr;
+ currAktPos = this.actPos;
+ this.actPos = 0;
+ result = myCoreNext (delete, pattern);
+ this.actPos = currAktPos;
+
+ this.actBuffer = currBuffer;
+ this.myMatcher = aktMatcher;
+ this.skipped = true;
+
+ return result;
+ }
+
+ /**
+ * Calls the next() method internally to get the next String, and
+ * trys to apply a locale which is only applied if the radix is 10
+ * and useLocale is <code> true </code>. Afterwards it is tried to
+ * call the Constructor of a {@link BigInteger} with the given
+ * radix.
+ *
+ * @param radix The radix to use.
+ * @param delete If the found String should be removed from input or
+ * not.
+ * @param name name of "BigInteger" in case of an Error.
+ * @return Returns the new BigInteger created if there is no Error.
+ * @throws InputMismatchException
+ * If there is a {@link ParseException} or a {@link NumberFormatException}.
+ */
+ private BigInteger myNextBigInteger (final int radix, final boolean delete,
+ final String name)
+ {
+ BigInteger rc;
+ String tmp = myPrepareForNext (this.p, delete);
+
+ try
+ {
+ tmp = myApplyLocale (tmp, radix);
+ rc = new BigInteger (tmp, radix);
+ return rc;
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ catch (ParseException e)
+ {
+ }
+ throw new InputMismatchException (ERR_PREFIX + tmp + IS_NOT + name);
+ }
+
+ /**
+ * Checks if the next String is either "true" or "false", otherwise
+ * an {@link InputMismatchException} is thrown. It ignores the case
+ * of the string so that "true" and "TRUE" and even "TrUe" are
+ * accepted.
+ *
+ * @param delete Should the found value be removed from the input or
+ * not.
+ * @return Returns the boolean value (if it is a boolean).
+ * @throws InputMismatchException
+ * If the next String is not a boolean.
+ */
+ private boolean myNextBoolean (final boolean delete) throws
+ InputMismatchException
+ {
+ String tmp = myPrepareForNext (this.p, delete);
+ if (tmp.equalsIgnoreCase ("true"))
+ {
+ return true;
+ }
+ else if (tmp.equalsIgnoreCase ("false"))
+ {
+ return false;
+ }
+ else
+ {
+ throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BOOLEAN);
+ }
+ }
+
+ /**
+ * Calls the {@link #myPrepareForNext(Pattern, boolean)} which calls
+ * the {@link #myCoreNext(boolean, Pattern)} to return the next
+ * String matching the current delimier. Afterwards it is tryed to
+ * convert the String into a byte. Any Error will lead into a {@link
+ * InputMismatchException}.
+ *
+ * @param radix The radix to use.
+ * @param delete Should the found String be removed from the input.
+ * @return Returns the byte value of the String.
+ * @throws InputMismatchException if the next String is not a byte.
+ */
+ private byte myNextByte (final int radix,
+ final boolean delete) throws InputMismatchException
+ {
+ byte rc;
+ String tmp = myPrepareForNext (this.p, delete);
+
+ try
+ {
+ tmp = myApplyLocale (tmp, radix);
+ rc = Byte.parseByte (tmp, radix);
+ return rc;
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ catch (ParseException e)
+ {
+ }
+ throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BYTE);
+ }
+
+ /**
+ * Tries to interpret the next String as a double value. To verify
+ * if the double value is correct, it is converted back to a String
+ * using the default Locale and this String is compared with the
+ * String from which the double was converted. If the two Strings
+ * don't match, an {@link InputMismatchException} is thrown.<br>
+ * <br> The radix used is always 10 even if the global radix is
+ * changed.
+ *
+ * @param delete Should the String be removed, if true it will be
+ * also removed if the String is not a double value.
+ * @return Returns the double value of the next String.
+ * @throws InputMismatchException if the next String is not a
+ * double.
+ */
+ private double myNextDouble (final boolean delete) throws
+ InputMismatchException
+ {
+ double rc;
+ String tmp = myPrepareForNext (this.p, delete);
+
+ try
+ {
+ tmp = myApplyLocale (tmp, 10);
+ rc = Double.parseDouble (tmp);
+ if (("" + rc).equals (tmp))
+ {
+ return rc;
+ }
+ }
+ catch (ParseException e)
+ {
+ }
+ throw new InputMismatchException (ERR_PREFIX + tmp + NOT_DOUBLE);
+ }
+
+ /**
+ * Tries to interpret the next String as an int value. Therfore
+ * {@link #myApplyLocale(String, int)} decides if the current Locale
+ * should be applied or not and then the result is parsed using
+ * {@link Integer#parseInt(String, int)}. Any Error will lead to an
+ * {@link InputMismatchException}.
+ *
+ * @param radix The radix to use.
+ * @param delete <code> true </code> if the String should be deleted
+ * from the input.
+ * @return Returns the int value of the String.
+ * @throws InputMismatchException if the next String is not an int.
+ */
+ private int myNextInt (final int radix,
+ final boolean delete) throws InputMismatchException
+ {
+ int rc;
+ String tmp = myPrepareForNext (this.p, delete);
+ try
+ {
+ tmp = myApplyLocale (tmp, radix);
+ rc = Integer.parseInt (tmp, radix);
+ return rc;
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ catch (ParseException e)
+ {
+ }
+ throw new InputMismatchException (ERR_PREFIX + tmp + NOT_INT);
+ }
+
+ /**
+ * Finds the next line using the {@link #NEW_LINE} constant which is
+ * set to the system specific line seperator.
+ *
+ * @param delete Should the found line be deleted from the input.
+ * @return Returns the current line.
+ */
+ private String myNextLine (final boolean delete)
+ {
+ String rc = null;
+ rc = myPrepareForNext (Pattern.compile (NEW_LINE), delete);
+ return rc;
+ }
+
+ /**
+ * Tries to interpret the next String as a long value with the given
+ * radix. Therfore the {@link Long#parseLong(String, int)} is called
+ * and every Error will lead into a {@link InputMismatchException}.
+ *
+ * @param radix The radix to be used.
+ * @param delete Should the found String be deleted from the input.
+ * @return the long value of the next String.
+ * @throws InputMismatchException if the next String is not a long.
+ */
+ private long myNextLong (final int radix,
+ final boolean delete) throws InputMismatchException
+ {
+ long rc;
+ String tmp = myPrepareForNext (this.p, delete);
+
+ try
+ {
+ tmp = myApplyLocale (tmp, radix);
+ rc = Long.parseLong (tmp, radix);
+ return rc;
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ catch (ParseException e)
+ {
+ }
+ throw new InputMismatchException (ERR_PREFIX + tmp + NOT_LONG);
+ }
+
+ /**
+ * Tries to interpret the next String as a short value with the
+ * given radix. Therfore the {@link Short#parseShort(String, int)}
+ * is called and every Error will lead into a {@link
+ * InputMismatchException} .
+ *
+ * @param radix
+ * The radix to be used.
+ * @param delete
+ * Should the found String be deleted from the input.
+ * @return the long value of the next String.
+ * @throws InputMismatchException
+ * if the next String is not a short.
+ */
+ private short myNextShort (final int radix,
+ final boolean delete) throws
+ InputMismatchException
+ {
+ short rc;
+ String tmp = myPrepareForNext (this.p, delete);
+
+ try
+ {
+ tmp = myApplyLocale (tmp, radix);
+ rc = Short.parseShort (tmp, radix);
+ return rc;
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ catch (ParseException e)
+ {
+ }
+ throw new InputMismatchException (ERR_PREFIX + tmp +
+ "\" is not a short");
+ }
+
+ /**
+ * Sets the current pattern to the given pattern and calls the
+ * {@link #myCoreNext(boolean, Pattern)}. Finally sets the pattern
+ * back to its old value.
+ *
+ * @param aktPattern Pattern to be used for the next match.
+ * @param delete Should the found String be deleted or not.
+ * @return Return the String returned from {@link
+ * #myCoreNext(boolean, Pattern)}.
+ */
+ private String myPrepareForNext (final Pattern aktPattern,
+ final boolean delete)
+ {
+
+ String rc;
+ Pattern oldPattern = this.p;
+ useDelimiter (aktPattern);
+
+ rc = myCoreNext (delete, aktPattern);
+
+ useDelimiter (oldPattern);
+
+ return rc;
+ }
+
+ /**
+ * Determinates if the last found can be used, so that after a
+ * hasNextXXX the nextXXX has not to search if nothing has
+ * changed.<br /> Used in {@link #myCoreNext(boolean, Pattern)}.
+ *
+ * @param aktP The pattern which should be checked.
+ * @return <code> true </code> if the searchresult is already ready.
+ */
+ private boolean shallUseLastFound (final Pattern aktP)
+ {
+ if (this.lastFoundPresent &&
+ this.lastPatternHash == aktP.hashCode () &&
+ this.last_RegionStart == this.myMatcher.regionStart () &&
+ this.last_anchor == this.myMatcher.hasAnchoringBounds () &&
+ this.last_transparent == this.myMatcher.hasTransparentBounds ())
+ {
+ if (this.last_RegionEnd != this.myMatcher.regionEnd ())
+ {
+ int tmpVal =
+ this.myMatcher.regionEnd () -
+ this.last_RegionEnd - this.MAX_PREFIX;
+ if (tmpVal > 0 && tmpVal < 20)
+ {
+ this.last_RegionEnd =
+ this.myMatcher.regionEnd ();
+ return true;
+ }
+ }
+ else
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/libjava/classpath/java/util/Stack.java b/libjava/classpath/java/util/Stack.java
index 404a146c272..1d8792882ef 100644
--- a/libjava/classpath/java/util/Stack.java
+++ b/libjava/classpath/java/util/Stack.java
@@ -102,13 +102,14 @@ public class Stack<T> extends Vector<T>
* @return the Object popped from the stack
* @throws EmptyStackException if the stack is empty
*/
+ @SuppressWarnings("unchecked")
public synchronized T pop()
{
if (elementCount == 0)
throw new EmptyStackException();
modCount++;
- T obj = elementData[--elementCount];
+ T obj = (T) elementData[--elementCount];
// Set topmost element to null to assist the gc in cleanup.
elementData[elementCount] = null;
@@ -121,12 +122,13 @@ public class Stack<T> extends Vector<T>
* @return the top Object on the stack
* @throws EmptyStackException if the stack is empty
*/
+ @SuppressWarnings("unchecked")
public synchronized T peek()
{
if (elementCount == 0)
throw new EmptyStackException();
- return elementData[elementCount - 1];
+ return (T) elementData[elementCount - 1];
}
/**
diff --git a/libjava/classpath/java/util/TimeZone.java b/libjava/classpath/java/util/TimeZone.java
index 5329e06c11f..681a6a24ad4 100644
--- a/libjava/classpath/java/util/TimeZone.java
+++ b/libjava/classpath/java/util/TimeZone.java
@@ -40,7 +40,9 @@ exception statement from your version. */
package java.util;
import gnu.classpath.SystemProperties;
+import gnu.java.lang.CPStringBuilder;
import gnu.java.util.ZoneInfo;
+
import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -1404,7 +1406,7 @@ public abstract class TimeZone implements java.io.Serializable, Cloneable
{
int offset = getRawOffset() + (dst ? getDSTSavings() : 0);
- StringBuffer sb = new StringBuffer(9);
+ CPStringBuilder sb = new CPStringBuilder(9);
sb.append("GMT");
offset = offset / (1000 * 60);
@@ -1564,7 +1566,7 @@ public abstract class TimeZone implements java.io.Serializable, Cloneable
}
// Custom IDs have to be normalized
- StringBuffer sb = new StringBuffer(9);
+ CPStringBuilder sb = new CPStringBuilder(9);
sb.append("GMT");
sb.append(offset_direction >= 0 ? '+' : '-');
diff --git a/libjava/classpath/java/util/TreeMap.java b/libjava/classpath/java/util/TreeMap.java
index f54cbc336ec..1068100d562 100644
--- a/libjava/classpath/java/util/TreeMap.java
+++ b/libjava/classpath/java/util/TreeMap.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -2720,7 +2722,7 @@ public class TreeMap<K, V> extends AbstractMap<K, V>
public String toString()
{
- StringBuilder r = new StringBuilder("{");
+ CPStringBuilder r = new CPStringBuilder("{");
final Iterator<Entry<DK,DV>> it = entrySet().iterator();
while (it.hasNext())
{
@@ -3158,7 +3160,7 @@ public class TreeMap<K, V> extends AbstractMap<K, V>
public String toString()
{
- StringBuilder r = new StringBuilder("[");
+ CPStringBuilder r = new CPStringBuilder("[");
final Iterator<D> it = iterator();
while (it.hasNext())
{
diff --git a/libjava/classpath/java/util/Vector.java b/libjava/classpath/java/util/Vector.java
index ea29ce09315..101a78ddac2 100644
--- a/libjava/classpath/java/util/Vector.java
+++ b/libjava/classpath/java/util/Vector.java
@@ -95,7 +95,7 @@ public class Vector<T> extends AbstractList<T>
* in positions 0 through elementCount - 1, and all remaining slots are null.
* @serial the elements
*/
- protected T[] elementData;
+ protected Object[] elementData;
/**
* The number of elements currently in the vector, also returned by
@@ -133,7 +133,7 @@ public class Vector<T> extends AbstractList<T>
public Vector(Collection<? extends T> c)
{
elementCount = c.size();
- elementData = c.toArray((T[]) new Object[elementCount]);
+ elementData = c.toArray(new Object[elementCount]);
}
/**
@@ -149,7 +149,7 @@ public class Vector<T> extends AbstractList<T>
{
if (initialCapacity < 0)
throw new IllegalArgumentException();
- elementData = (T[]) new Object[initialCapacity];
+ elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
@@ -295,11 +295,12 @@ public class Vector<T> extends AbstractList<T>
return i < elementCount;
}
+ @SuppressWarnings("unchecked")
public T nextElement()
{
if (i >= elementCount)
throw new NoSuchElementException();
- return elementData[i++];
+ return (T) elementData[i++];
}
};
}
@@ -385,10 +386,11 @@ public class Vector<T> extends AbstractList<T>
* @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
* @see #get(int)
*/
+ @SuppressWarnings("unchecked")
public synchronized T elementAt(int index)
{
checkBoundExclusive(index);
- return elementData[index];
+ return (T) elementData[index];
}
/**
@@ -397,12 +399,13 @@ public class Vector<T> extends AbstractList<T>
* @return the first Object in the Vector
* @throws NoSuchElementException the Vector is empty
*/
+ @SuppressWarnings("unchecked")
public synchronized T firstElement()
{
if (elementCount == 0)
throw new NoSuchElementException();
- return elementData[0];
+ return (T) elementData[0];
}
/**
@@ -411,12 +414,13 @@ public class Vector<T> extends AbstractList<T>
* @return the last Object in the Vector
* @throws NoSuchElementException the Vector is empty
*/
+ @SuppressWarnings("unchecked")
public synchronized T lastElement()
{
if (elementCount == 0)
throw new NoSuchElementException();
- return elementData[elementCount - 1];
+ return (T) elementData[elementCount - 1];
}
/**
@@ -604,10 +608,11 @@ public class Vector<T> extends AbstractList<T>
* @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
* @since 1.2
*/
+ @SuppressWarnings("unchecked")
public synchronized T set(int index, T element)
{
checkBoundExclusive(index);
- T temp = elementData[index];
+ T temp = (T) elementData[index];
elementData[index] = element;
return temp;
}
@@ -660,10 +665,11 @@ public class Vector<T> extends AbstractList<T>
* @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
* @since 1.2
*/
+ @SuppressWarnings("unchecked")
public synchronized T remove(int index)
{
checkBoundExclusive(index);
- T temp = elementData[index];
+ T temp = (T) elementData[index];
modCount++;
elementCount--;
if (index < elementCount)
@@ -903,7 +909,7 @@ public class Vector<T> extends AbstractList<T>
// use of a negative index will cause an ArrayIndexOutOfBoundsException
// with no effort on our part.
if (index > elementCount)
- throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount);
+ raiseBoundsError(index, " > ");
}
/**
@@ -918,10 +924,25 @@ public class Vector<T> extends AbstractList<T>
// use of a negative index will cause an ArrayIndexOutOfBoundsException
// with no effort on our part.
if (index >= elementCount)
- throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
+ raiseBoundsError(index, " >= ");
}
/**
+ * Raise the ArrayIndexOfOutBoundsException.
+ *
+ * @param index the index of the access
+ * @param operator the operator to include in the error message
+ * @throws IndexOutOfBoundsException unconditionally
+ */
+ private void raiseBoundsError(int index, String operator)
+ {
+ // Implementaion note: put in a separate method to make the JITs job easier
+ // (separate common from uncommon code at method boundaries when trivial to
+ // do so).
+ throw new ArrayIndexOutOfBoundsException(index + operator + elementCount);
+ }
+
+ /**
* Serializes this object to the given stream.
*
* @param s the stream to write to
diff --git a/libjava/classpath/java/util/logging/FileHandler.java b/libjava/classpath/java/util/logging/FileHandler.java
index 357d51e14fc..deba5c2e55c 100644
--- a/libjava/classpath/java/util/logging/FileHandler.java
+++ b/libjava/classpath/java/util/logging/FileHandler.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.util.logging;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
@@ -478,7 +480,7 @@ public class FileHandler
int uniqueNumber,
int count)
{
- StringBuffer buf = new StringBuffer(pattern);
+ CPStringBuilder buf = new CPStringBuilder(pattern);
String replaceWith;
boolean foundGeneration = false;
diff --git a/libjava/classpath/java/util/logging/Logger.java b/libjava/classpath/java/util/logging/Logger.java
index f7157c17698..cddc02d1c9c 100644
--- a/libjava/classpath/java/util/logging/Logger.java
+++ b/libjava/classpath/java/util/logging/Logger.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.util.logging;
+import gnu.java.lang.CPStringBuilder;
+
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
@@ -776,7 +778,7 @@ public class Logger
{
if (isLoggable(Level.FINER))
{
- StringBuffer buf = new StringBuffer(80);
+ CPStringBuilder buf = new CPStringBuilder(80);
buf.append("ENTRY");
for (int i = 0; i < params.length; i++)
{
diff --git a/libjava/classpath/java/util/logging/SimpleFormatter.java b/libjava/classpath/java/util/logging/SimpleFormatter.java
index 2ebb1a1485f..da731f2b1de 100644
--- a/libjava/classpath/java/util/logging/SimpleFormatter.java
+++ b/libjava/classpath/java/util/logging/SimpleFormatter.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util.logging;
+import gnu.java.lang.CPStringBuilder;
+
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
@@ -98,7 +100,7 @@ public class SimpleFormatter
*/
public String format(LogRecord record)
{
- StringBuffer buf = new StringBuffer(180);
+ CPStringBuilder buf = new CPStringBuilder(180);
if (dateFormat == null)
dateFormat = DateFormat.getDateTimeInstance();
diff --git a/libjava/classpath/java/util/logging/XMLFormatter.java b/libjava/classpath/java/util/logging/XMLFormatter.java
index 8f5769be1b9..194fcd238ce 100644
--- a/libjava/classpath/java/util/logging/XMLFormatter.java
+++ b/libjava/classpath/java/util/logging/XMLFormatter.java
@@ -39,6 +39,8 @@ exception statement from your version. */
package java.util.logging;
+import gnu.java.lang.CPStringBuilder;
+
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;
@@ -86,10 +88,10 @@ public class XMLFormatter
/**
* Appends a line consisting of indentation, opening element tag,
* element content, closing element tag and line separator to
- * a StringBuffer, provided that the element content is
+ * a CPStringBuilder, provided that the element content is
* actually existing.
*
- * @param buf the StringBuffer to which the line will be appended.
+ * @param buf the CPStringBuilder to which the line will be appended.
*
* @param indent the indentation level.
*
@@ -98,7 +100,7 @@ public class XMLFormatter
* @param content the element content, or <code>null</code> to
* have no output whatsoever appended to <code>buf</code>.
*/
- private static void appendTag(StringBuffer buf, int indent,
+ private static void appendTag(CPStringBuilder buf, int indent,
String tag, String content)
{
int i;
@@ -163,9 +165,9 @@ public class XMLFormatter
/**
* Appends a line consisting of indentation, opening element tag,
* numeric element content, closing element tag and line separator
- * to a StringBuffer.
+ * to a CPStringBuilder.
*
- * @param buf the StringBuffer to which the line will be appended.
+ * @param buf the CPStringBuilder to which the line will be appended.
*
* @param indent the indentation level.
*
@@ -173,7 +175,7 @@ public class XMLFormatter
*
* @param content the element content.
*/
- private static void appendTag(StringBuffer buf, int indent,
+ private static void appendTag(CPStringBuilder buf, int indent,
String tag, long content)
{
appendTag(buf, indent, tag, Long.toString(content));
@@ -182,7 +184,7 @@ public class XMLFormatter
public String format(LogRecord record)
{
- StringBuffer buf = new StringBuffer(400);
+ CPStringBuilder buf = new CPStringBuilder(400);
Level level = record.getLevel();
long millis = record.getMillis();
Object[] params = record.getParameters();
@@ -314,10 +316,10 @@ public class XMLFormatter
*/
public String getHead(Handler h)
{
- StringBuffer buf;
+ CPStringBuilder buf;
String encoding;
- buf = new StringBuffer(80);
+ buf = new CPStringBuilder(80);
buf.append("<?xml version=\"1.0\" encoding=\"");
encoding = h.getEncoding();
diff --git a/libjava/classpath/java/util/prefs/AbstractPreferences.java b/libjava/classpath/java/util/prefs/AbstractPreferences.java
index f3a62e6980d..9562e1bbf5b 100644
--- a/libjava/classpath/java/util/prefs/AbstractPreferences.java
+++ b/libjava/classpath/java/util/prefs/AbstractPreferences.java
@@ -38,7 +38,8 @@ exception statement from your version. */
package java.util.prefs;
-import gnu.java.util.prefs.EventDispatcher;
+import gnu.classpath.toolkit.DefaultDaemonThreadFactory;
+import gnu.java.lang.CPStringBuilder;
import gnu.java.util.prefs.NodeWriter;
import java.io.ByteArrayOutputStream;
@@ -49,6 +50,8 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
/**
* Partial implementation of a Preference node.
@@ -841,7 +844,7 @@ public abstract class AbstractPreferences extends Preferences {
* Helper method for encoding an array of bytes as a Base64 String.
*/
private static String encode64(byte[] b) {
- StringBuffer sb = new StringBuffer((b.length/3)*4);
+ CPStringBuilder sb = new CPStringBuilder((b.length/3)*4);
int i = 0;
int remaining = b.length;
@@ -1236,17 +1239,18 @@ public abstract class AbstractPreferences extends Preferences {
*/
private void fire(final PreferenceChangeEvent event)
{
- Iterator it = preferenceListeners.iterator();
- while (it.hasNext())
+ for (final PreferenceChangeListener listener : preferenceListeners)
{
- final PreferenceChangeListener l = (PreferenceChangeListener) it.next();
- EventDispatcher.dispatch(new Runnable()
- {
- public void run()
- {
- l.preferenceChange(event);
- }
- });
+ Runnable dispatcher = new Runnable() {
+ public void run()
+ {
+ listener.preferenceChange(event);
+ }
+ };
+
+ Executor executor =
+ Executors.newSingleThreadExecutor(new DefaultDaemonThreadFactory());
+ executor.execute(dispatcher);
}
}
@@ -1258,20 +1262,21 @@ public abstract class AbstractPreferences extends Preferences {
*/
private void fire(final NodeChangeEvent event, final boolean added)
{
- Iterator it = nodeListeners.iterator();
- while (it.hasNext())
+ for (final NodeChangeListener listener : nodeListeners)
{
- final NodeChangeListener l = (NodeChangeListener) it.next();
- EventDispatcher.dispatch(new Runnable()
- {
- public void run()
- {
- if (added)
- l.childAdded(event);
- else
- l.childRemoved(event);
- }
- });
+ Runnable dispatcher = new Runnable() {
+ public void run()
+ {
+ if (added)
+ listener.childAdded(event);
+ else
+ listener.childRemoved(event);
+ }
+ };
+
+ Executor executor =
+ Executors.newSingleThreadExecutor(new DefaultDaemonThreadFactory());
+ executor.execute(dispatcher);
}
}
diff --git a/libjava/classpath/java/util/regex/Matcher.java b/libjava/classpath/java/util/regex/Matcher.java
index bf833673b0e..50cb065f287 100644
--- a/libjava/classpath/java/util/regex/Matcher.java
+++ b/libjava/classpath/java/util/regex/Matcher.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.util.regex;
+import gnu.java.lang.CPStringBuilder;
+
import gnu.java.util.regex.CharIndexed;
import gnu.java.util.regex.RE;
import gnu.java.util.regex.REMatch;
@@ -59,11 +61,45 @@ public final class Matcher implements MatchResult
private int appendPosition;
private REMatch match;
+ /**
+ * The start of the region of the input on which to match.
+ */
+ private int regionStart;
+
+ /**
+ * The end of the region of the input on which to match.
+ */
+ private int regionEnd;
+
+ /**
+ * True if the match process should look beyond the
+ * region marked by regionStart to regionEnd when
+ * performing lookAhead, lookBehind and boundary
+ * matching.
+ */
+ private boolean transparentBounds;
+
+ /**
+ * The flags that affect the anchoring bounds.
+ * If {@link #hasAnchoringBounds()} is {@code true},
+ * the match process will honour the
+ * anchoring bounds: ^, \A, \Z, \z and $. If
+ * {@link #hasAnchoringBounds()} is {@code false},
+ * the anchors are ignored and appropriate flags,
+ * stored in this variable, are used to provide this
+ * behaviour.
+ */
+ private int anchoringBounds;
+
Matcher(Pattern pattern, CharSequence input)
{
this.pattern = pattern;
this.input = input;
this.inputCharIndexed = RE.makeCharIndexed(input, 0);
+ regionStart = 0;
+ regionEnd = input.length();
+ transparentBounds = false;
+ anchoringBounds = 0;
}
/**
@@ -125,13 +161,17 @@ public final class Matcher implements MatchResult
public boolean find ()
{
boolean first = (match == null);
- match = pattern.getRE().getMatch(inputCharIndexed, position);
+ if (transparentBounds || (regionStart == 0 && regionEnd == input.length()))
+ match = pattern.getRE().getMatch(inputCharIndexed, position, anchoringBounds);
+ else
+ match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd),
+ position, anchoringBounds);
if (match != null)
{
int endIndex = match.getEndIndex();
// Are we stuck at the same position?
if (!first && endIndex == position)
- {
+ {
match = null;
// Not at the end of the input yet?
if (position < input.length() - 1)
@@ -156,7 +196,11 @@ public final class Matcher implements MatchResult
*/
public boolean find (int start)
{
- match = pattern.getRE().getMatch(inputCharIndexed, start);
+ if (transparentBounds || (regionStart == 0 && regionEnd == input.length()))
+ match = pattern.getRE().getMatch(inputCharIndexed, start, anchoringBounds);
+ else
+ match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd),
+ start, anchoringBounds);
if (match != null)
{
position = match.getEndIndex();
@@ -218,7 +262,12 @@ public final class Matcher implements MatchResult
public boolean lookingAt ()
{
- match = pattern.getRE().getMatch(inputCharIndexed, 0, RE.REG_FIX_STARTING_POSITION, null);
+ if (transparentBounds || (regionStart == 0 && regionEnd == input.length()))
+ match = pattern.getRE().getMatch(inputCharIndexed, regionStart,
+ anchoringBounds|RE.REG_FIX_STARTING_POSITION|RE.REG_ANCHORINDEX);
+ else
+ match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd), 0,
+ anchoringBounds|RE.REG_FIX_STARTING_POSITION);
if (match != null)
{
if (match.getStartIndex() == 0)
@@ -243,7 +292,12 @@ public final class Matcher implements MatchResult
*/
public boolean matches ()
{
- match = pattern.getRE().getMatch(inputCharIndexed, 0, RE.REG_TRY_ENTIRE_MATCH|RE.REG_FIX_STARTING_POSITION, null);
+ if (transparentBounds || (regionStart == 0 && regionEnd == input.length()))
+ match = pattern.getRE().getMatch(inputCharIndexed, regionStart,
+ anchoringBounds|RE.REG_TRY_ENTIRE_MATCH|RE.REG_FIX_STARTING_POSITION|RE.REG_ANCHORINDEX);
+ else
+ match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd), 0,
+ anchoringBounds|RE.REG_TRY_ENTIRE_MATCH|RE.REG_FIX_STARTING_POSITION);
if (match != null)
{
if (match.getStartIndex() == 0)
@@ -265,15 +319,40 @@ public final class Matcher implements MatchResult
return pattern;
}
+ /**
+ * Resets the internal state of the matcher, including
+ * resetting the region to its default state of encompassing
+ * the whole input. The state of {@link #hasTransparentBounds()}
+ * and {@link #hasAnchoringBounds()} are unaffected.
+ *
+ * @return a reference to this matcher.
+ * @see #regionStart()
+ * @see #regionEnd()
+ * @see #hasTransparentBounds()
+ * @see #hasAnchoringBounds()
+ */
public Matcher reset ()
{
position = 0;
match = null;
+ regionStart = 0;
+ regionEnd = input.length();
+ appendPosition = 0;
return this;
}
/**
- * @param input The new input character sequence
+ * Resets the internal state of the matcher, including
+ * resetting the region to its default state of encompassing
+ * the whole input. The state of {@link #hasTransparentBounds()}
+ * and {@link #hasAnchoringBounds()} are unaffected.
+ *
+ * @param input The new input character sequence.
+ * @return a reference to this matcher.
+ * @see #regionStart()
+ * @see #regionEnd()
+ * @see #hasTransparentBounds()
+ * @see #hasAnchoringBounds()
*/
public Matcher reset (CharSequence input)
{
@@ -283,7 +362,7 @@ public final class Matcher implements MatchResult
}
/**
- * @returns the index of a capturing group in this matcher's pattern
+ * @return the index of a capturing group in this matcher's pattern
*
* @exception IllegalStateException If no match has yet been attempted,
* or if the previous match operation failed
@@ -312,6 +391,7 @@ public final class Matcher implements MatchResult
/**
* @return True if and only if the matcher hit the end of input.
+ * @since 1.5
*/
public boolean hitEnd()
{
@@ -323,10 +403,12 @@ public final class Matcher implements MatchResult
*/
public String toString()
{
- StringBuilder sb = new StringBuilder();
+ CPStringBuilder sb = new CPStringBuilder();
sb.append(this.getClass().getName())
.append("[pattern=").append(pattern.pattern())
- .append(" region=").append("0").append(",").append(input.length())
+ .append(" region=").append(regionStart).append(",").append(regionEnd)
+ .append(" anchoringBounds=").append(anchoringBounds == 0)
+ .append(" transparentBounds=").append(transparentBounds)
.append(" lastmatch=").append(match == null ? "" : match.toString())
.append("]");
return sb.toString();
@@ -336,4 +418,193 @@ public final class Matcher implements MatchResult
{
if (match == null) throw new IllegalStateException();
}
+
+ /**
+ * <p>
+ * Defines the region of the input on which to match.
+ * By default, the {@link Matcher} attempts to match
+ * the whole string (from 0 to the length of the input),
+ * but a region between {@code start} (inclusive) and
+ * {@code end} (exclusive) on which to match may instead
+ * be defined using this method.
+ * </p>
+ * <p>
+ * The behaviour of region matching is further affected
+ * by the use of transparent or opaque bounds (see
+ * {@link #useTransparentBounds(boolean)}) and whether or not
+ * anchors ({@code ^} and {@code $}) are in use
+ * (see {@link #useAnchoringBounds(boolean)}). With transparent
+ * bounds, the matcher is aware of input outside the bounds
+ * set by this method, whereas, with opaque bounds (the default)
+ * only the input within the bounds is used. The use of
+ * anchors are affected by this setting; with transparent
+ * bounds, anchors will match the beginning of the real input,
+ * while with opaque bounds they match the beginning of the
+ * region. {@link #useAnchoringBounds(boolean)} can be used
+ * to turn on or off the matching of anchors.
+ * </p>
+ *
+ * @param start the start of the region (inclusive).
+ * @param end the end of the region (exclusive).
+ * @return a reference to this matcher.
+ * @throws IndexOutOfBoundsException if either {@code start} or
+ * {@code end} are less than zero,
+ * if either {@code start} or
+ * {@code end} are greater than the
+ * length of the input, or if
+ * {@code start} is greater than
+ * {@code end}.
+ * @see #regionStart()
+ * @see #regionEnd()
+ * @see #hasTransparentBounds()
+ * @see #useTransparentBounds(boolean)
+ * @see #hasAnchoringBounds()
+ * @see #useAnchoringBounds(boolean)
+ * @since 1.5
+ */
+ public Matcher region(int start, int end)
+ {
+ int length = input.length();
+ if (start < 0)
+ throw new IndexOutOfBoundsException("The start position was less than zero.");
+ if (start >= length)
+ throw new IndexOutOfBoundsException("The start position is after the end of the input.");
+ if (end < 0)
+ throw new IndexOutOfBoundsException("The end position was less than zero.");
+ if (end > length)
+ throw new IndexOutOfBoundsException("The end position is after the end of the input.");
+ if (start > end)
+ throw new IndexOutOfBoundsException("The start position is after the end position.");
+ reset();
+ regionStart = start;
+ regionEnd = end;
+ return this;
+ }
+
+ /**
+ * The start of the region on which to perform matches (inclusive).
+ *
+ * @return the start index of the region.
+ * @see #region(int,int)
+ * #see #regionEnd()
+ * @since 1.5
+ */
+ public int regionStart()
+ {
+ return regionStart;
+ }
+
+ /**
+ * The end of the region on which to perform matches (exclusive).
+ *
+ * @return the end index of the region.
+ * @see #region(int,int)
+ * @see #regionStart()
+ * @since 1.5
+ */
+ public int regionEnd()
+ {
+ return regionEnd;
+ }
+
+ /**
+ * Returns true if the bounds of the region marked by
+ * {@link #regionStart()} and {@link #regionEnd()} are
+ * transparent. When these bounds are transparent, the
+ * matching process can look beyond them to perform
+ * lookahead, lookbehind and boundary matching operations.
+ * By default, the bounds are opaque.
+ *
+ * @return true if the bounds of the matching region are
+ * transparent.
+ * @see #useTransparentBounds(boolean)
+ * @see #region(int,int)
+ * @see #regionStart()
+ * @see #regionEnd()
+ * @since 1.5
+ */
+ public boolean hasTransparentBounds()
+ {
+ return transparentBounds;
+ }
+
+ /**
+ * Sets the transparency of the bounds of the region
+ * marked by {@link #regionStart()} and {@link #regionEnd()}.
+ * A value of {@code true} makes the bounds transparent,
+ * so the matcher can see beyond them to perform lookahead,
+ * lookbehind and boundary matching operations. A value
+ * of {@code false} (the default) makes the bounds opaque,
+ * restricting the match to the input region denoted
+ * by {@link #regionStart()} and {@link #regionEnd()}.
+ *
+ * @param transparent true if the bounds should be transparent.
+ * @return a reference to this matcher.
+ * @see #hasTransparentBounds()
+ * @see #region(int,int)
+ * @see #regionStart()
+ * @see #regionEnd()
+ * @since 1.5
+ */
+ public Matcher useTransparentBounds(boolean transparent)
+ {
+ transparentBounds = transparent;
+ return this;
+ }
+
+ /**
+ * Returns true if the matcher will honour the use of
+ * the anchoring bounds: {@code ^}, {@code \A}, {@code \Z},
+ * {@code \z} and {@code $}. By default, the anchors
+ * are used. Note that the effect of the anchors is
+ * also affected by {@link #hasTransparentBounds()}.
+ *
+ * @return true if the matcher will attempt to match
+ * the anchoring bounds.
+ * @see #useAnchoringBounds(boolean)
+ * @see #hasTransparentBounds()
+ * @since 1.5
+ */
+ public boolean hasAnchoringBounds()
+ {
+ return anchoringBounds == 0;
+ }
+
+ /**
+ * Enables or disables the use of the anchoring bounds:
+ * {@code ^}, {@code \A}, {@code \Z}, {@code \z} and
+ * {@code $}. By default, their use is enabled. When
+ * disabled, the matcher will not attempt to match
+ * the anchors.
+ *
+ * @param useAnchors true if anchoring bounds should be used.
+ * @return a reference to this matcher.
+ * @since 1.5
+ * @see #hasAnchoringBounds()
+ */
+ public Matcher useAnchoringBounds(boolean useAnchors)
+ {
+ if (useAnchors)
+ anchoringBounds = 0;
+ else
+ anchoringBounds = RE.REG_NOTBOL|RE.REG_NOTEOL;
+ return this;
+ }
+
+ /**
+ * Returns a read-only snapshot of the current state of
+ * the {@link Matcher} as a {@link MatchResult}. Any
+ * subsequent changes to this instance are not reflected
+ * in the returned {@link MatchResult}.
+ *
+ * @return a {@link MatchResult} instance representing the
+ * current state of the {@link Matcher}.
+ */
+ public MatchResult toMatchResult()
+ {
+ Matcher snapshot = new Matcher(pattern, input);
+ snapshot.match = (REMatch) match.clone();
+ return snapshot;
+ }
+
}
diff --git a/libjava/classpath/java/util/regex/Pattern.java b/libjava/classpath/java/util/regex/Pattern.java
index 217ce0862a9..35ec0b89eb6 100644
--- a/libjava/classpath/java/util/regex/Pattern.java
+++ b/libjava/classpath/java/util/regex/Pattern.java
@@ -191,7 +191,7 @@ public final class Pattern implements Serializable
public String[] split (CharSequence input, int limit)
{
Matcher matcher = new Matcher(this, input);
- ArrayList list = new ArrayList();
+ ArrayList<String> list = new ArrayList<String>();
int empties = 0;
int count = 0;
int start = 0;
@@ -251,9 +251,7 @@ public final class Pattern implements Serializable
list.add(t);
}
- String[] output = new String [list.size()];
- list.toArray(output);
- return output;
+ return list.toArray(new String[list.size()]);
}
public String pattern ()
diff --git a/libjava/classpath/java/util/regex/PatternSyntaxException.java b/libjava/classpath/java/util/regex/PatternSyntaxException.java
index 41e650d324b..38e27db2709 100644
--- a/libjava/classpath/java/util/regex/PatternSyntaxException.java
+++ b/libjava/classpath/java/util/regex/PatternSyntaxException.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package java.util.regex;
+import gnu.java.lang.CPStringBuilder;
+
/**
* Indicates illegal pattern for regular expression.
* Includes state to inspect the pattern and what and where the expression
@@ -115,7 +117,7 @@ public class PatternSyntaxException extends IllegalArgumentException
public String getMessage()
{
String lineSep = System.getProperty("line.separator");
- StringBuffer sb = new StringBuffer(desc);
+ CPStringBuilder sb = new CPStringBuilder(desc);
sb.append(lineSep);
sb.append('\t');
sb.append(pattern);
diff --git a/libjava/classpath/java/util/zip/Deflater.java b/libjava/classpath/java/util/zip/Deflater.java
index e97c6054ff4..41d9881448c 100644
--- a/libjava/classpath/java/util/zip/Deflater.java
+++ b/libjava/classpath/java/util/zip/Deflater.java
@@ -241,7 +241,6 @@ public class Deflater
/**
* Gets the number of input bytes processed so far.
*/
- @Deprecated
public int getTotalIn()
{
return (int) engine.getTotalIn();
@@ -259,7 +258,6 @@ public class Deflater
/**
* Gets the number of output bytes so far.
*/
- @Deprecated
public int getTotalOut()
{
return (int) totalOut;
diff --git a/libjava/classpath/java/util/zip/Inflater.java b/libjava/classpath/java/util/zip/Inflater.java
index 509b9576429..e3e555ab995 100644
--- a/libjava/classpath/java/util/zip/Inflater.java
+++ b/libjava/classpath/java/util/zip/Inflater.java
@@ -246,7 +246,6 @@ public class Inflater
* Gets the total number of processed compressed input bytes.
* @return the total number of bytes of processed input bytes.
*/
- @Deprecated
public int getTotalIn()
{
return (int) (totalIn - getRemaining());
@@ -266,7 +265,6 @@ public class Inflater
* Gets the total number of output bytes returned by inflate().
* @return the total number of output bytes.
*/
- @Deprecated
public int getTotalOut()
{
return (int) totalOut;
diff --git a/libjava/classpath/java/util/zip/ZipEntry.java b/libjava/classpath/java/util/zip/ZipEntry.java
index 893f043746d..a6d01af5ff6 100644
--- a/libjava/classpath/java/util/zip/ZipEntry.java
+++ b/libjava/classpath/java/util/zip/ZipEntry.java
@@ -50,23 +50,39 @@ import java.util.Calendar;
*/
public class ZipEntry implements ZipConstants, Cloneable
{
- private static final int KNOWN_SIZE = 1;
- private static final int KNOWN_CSIZE = 2;
- private static final int KNOWN_CRC = 4;
- private static final int KNOWN_TIME = 8;
- private static final int KNOWN_EXTRA = 16;
-
- private static Calendar cal;
-
- private String name;
+ private static final byte KNOWN_SIZE = 1;
+ private static final byte KNOWN_CSIZE = 2;
+ private static final byte KNOWN_CRC = 4;
+ private static final byte KNOWN_TIME = 8;
+ private static final byte KNOWN_DOSTIME = 16;
+ private static final byte KNOWN_EXTRA = 32;
+
+ /** Immutable name of the entry */
+ private final String name;
+ /** Uncompressed size */
private int size;
+ /** Compressed size */
private long compressedSize = -1;
+ /** CRC of uncompressed data */
private int crc;
+ /** Comment or null if none */
+ private String comment = null;
+ /** The compression method. Either DEFLATED or STORED, by default -1. */
+ private byte method = -1;
+ /** Flags specifying what we know about this entry */
+ private byte known = 0;
+ /**
+ * The 32bit DOS encoded format for the time of this entry. Only valid if
+ * KNOWN_DOSTIME is set in known.
+ */
private int dostime;
- private short known = 0;
- private short method = -1;
+ /**
+ * The 64bit Java encoded millisecond time since the beginning of the epoch.
+ * Only valid if KNOWN_TIME is set in known.
+ */
+ private long time;
+ /** Extra data */
private byte[] extra = null;
- private String comment = null;
int flags; /* used by ZipOutputStream */
int offset; /* used by ZipFile and ZipOutputStream */
@@ -113,6 +129,7 @@ public class ZipEntry implements ZipConstants, Cloneable
compressedSize = e.compressedSize;
crc = e.crc;
dostime = e.dostime;
+ time = e.time;
method = e.method;
extra = e.extra;
comment = e.comment;
@@ -121,37 +138,60 @@ public class ZipEntry implements ZipConstants, Cloneable
final void setDOSTime(int dostime)
{
this.dostime = dostime;
- known |= KNOWN_TIME;
+ known |= KNOWN_DOSTIME;
+ known &= ~KNOWN_TIME;
}
final int getDOSTime()
{
- if ((known & KNOWN_TIME) == 0)
- return 0;
- else
+ if ((known & KNOWN_DOSTIME) != 0)
return dostime;
+ else if ((known & KNOWN_TIME) != 0)
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(time);
+ dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25
+ | (cal.get(Calendar.MONTH) + 1) << 21
+ | (cal.get(Calendar.DAY_OF_MONTH)) << 16
+ | (cal.get(Calendar.HOUR_OF_DAY)) << 11
+ | (cal.get(Calendar.MINUTE)) << 5
+ | (cal.get(Calendar.SECOND)) >> 1;
+ known |= KNOWN_DOSTIME;
+ return dostime;
+ }
+ else
+ return 0;
}
/**
* Creates a copy of this zip entry.
*/
- /**
- * Clones the entry.
- */
public Object clone()
{
- try
+ // JCL defines this as being the same as the copy constructor above,
+ // except that value of the "extra" field is also copied. Take care
+ // that in the case of a subclass we use clone() rather than the copy
+ // constructor.
+ ZipEntry clone;
+ if (this.getClass() == ZipEntry.class)
+ clone = new ZipEntry(this);
+ else
{
- // The JCL says that the `extra' field is also copied.
- ZipEntry clone = (ZipEntry) super.clone();
- if (extra != null)
- clone.extra = (byte[]) extra.clone();
- return clone;
+ try
+ {
+ clone = (ZipEntry) super.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ throw new InternalError();
+ }
}
- catch (CloneNotSupportedException ex)
+ if (extra != null)
{
- throw new InternalError();
+ clone.extra = new byte[extra.length];
+ System.arraycopy(extra, 0, clone.extra, 0, extra.length);
}
+ return clone;
}
/**
@@ -169,18 +209,9 @@ public class ZipEntry implements ZipConstants, Cloneable
*/
public void setTime(long time)
{
- Calendar cal = getCalendar();
- synchronized (cal)
- {
- cal.setTimeInMillis(time);
- dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25
- | (cal.get(Calendar.MONTH) + 1) << 21
- | (cal.get(Calendar.DAY_OF_MONTH)) << 16
- | (cal.get(Calendar.HOUR_OF_DAY)) << 11
- | (cal.get(Calendar.MINUTE)) << 5
- | (cal.get(Calendar.SECOND)) >> 1;
- }
+ this.time = time;
this.known |= KNOWN_TIME;
+ this.known &= ~KNOWN_DOSTIME;
}
/**
@@ -192,39 +223,34 @@ public class ZipEntry implements ZipConstants, Cloneable
// The extra bytes might contain the time (posix/unix extension)
parseExtra();
- if ((known & KNOWN_TIME) == 0)
- return -1;
-
- int sec = 2 * (dostime & 0x1f);
- int min = (dostime >> 5) & 0x3f;
- int hrs = (dostime >> 11) & 0x1f;
- int day = (dostime >> 16) & 0x1f;
- int mon = ((dostime >> 21) & 0xf) - 1;
- int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */
-
- try
- {
- cal = getCalendar();
- synchronized (cal)
- {
- cal.set(year, mon, day, hrs, min, sec);
- return cal.getTimeInMillis();
- }
- }
- catch (RuntimeException ex)
+ if ((known & KNOWN_TIME) != 0)
+ return time;
+ else if ((known & KNOWN_DOSTIME) != 0)
{
- /* Ignore illegal time stamp */
- known &= ~KNOWN_TIME;
- return -1;
+ int sec = 2 * (dostime & 0x1f);
+ int min = (dostime >> 5) & 0x3f;
+ int hrs = (dostime >> 11) & 0x1f;
+ int day = (dostime >> 16) & 0x1f;
+ int mon = ((dostime >> 21) & 0xf) - 1;
+ int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */
+
+ try
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.set(year, mon, day, hrs, min, sec);
+ time = cal.getTimeInMillis();
+ known |= KNOWN_TIME;
+ return time;
+ }
+ catch (RuntimeException ex)
+ {
+ /* Ignore illegal time stamp */
+ known &= ~KNOWN_TIME;
+ return -1;
+ }
}
- }
-
- private static synchronized Calendar getCalendar()
- {
- if (cal == null)
- cal = Calendar.getInstance();
-
- return cal;
+ else
+ return -1;
}
/**
@@ -298,7 +324,7 @@ public class ZipEntry implements ZipConstants, Cloneable
if (method != ZipOutputStream.STORED
&& method != ZipOutputStream.DEFLATED)
throw new IllegalArgumentException();
- this.method = (short) method;
+ this.method = (byte) method;
}
/**
diff --git a/libjava/classpath/java/util/zip/ZipFile.java b/libjava/classpath/java/util/zip/ZipFile.java
index 3b34bd1f50b..7cf7007ed8f 100644
--- a/libjava/classpath/java/util/zip/ZipFile.java
+++ b/libjava/classpath/java/util/zip/ZipFile.java
@@ -340,7 +340,7 @@ public class ZipFile implements ZipConstants
}
catch (IOException ioe)
{
- return EmptyEnumeration.getInstance();
+ return new EmptyEnumeration<ZipEntry>();
}
}