diff options
author | doko <doko@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-10-21 17:55:01 +0000 |
---|---|---|
committer | doko <doko@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-10-21 17:55:01 +0000 |
commit | 2bc043354c4edb1f5aad751285060fb722a63ea1 (patch) | |
tree | 6de8da5758622565799768e49cd0de6698ca3cb8 /libjava/classpath/java | |
parent | be9f921eb27de7f5f22e4755df15340ab8042a09 (diff) | |
download | gcc-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')
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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 >= 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 "<modifier> <classname>(<paramtypes>) + * throws <exceptions>", 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 "<modifiers> <type> + * <class>.<fieldname>".<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 "<modifiers> <returntype> + * <methodname>(<paramtypes>) throws <exceptions>", 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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index >= 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>(); } } |