Imported GNU Classpath 0.90

Imported GNU Classpath 0.90
       * scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore.
       * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant.
       * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5.
       * java/lang/Math.java: New override file.
       * java/lang/Character.java: Merged from Classpath.
       (start, end): Now 'int's.
       (canonicalName): New field.
       (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants.
       (UnicodeBlock): Added argument.
       (of): New overload.
       (forName): New method.
       Updated unicode blocks.
       (sets): Updated.
       * sources.am: Regenerated.
       * Makefile.in: Likewise.

From-SVN: r111942
This commit is contained in:
Mark Wielaard 2006-03-10 21:46:48 +00:00
parent 27079765d0
commit 8aa540d2f7
1367 changed files with 188789 additions and 22762 deletions

View file

@ -423,7 +423,9 @@ public abstract class AbstractCollection implements Collection
* of the form "[a, b, ...]" where a and b etc are the results of calling
* toString on the elements of the collection. This implementation obtains an
* Iterator over the Collection and adds each element to a StringBuffer as it
* is returned by the iterator.
* is returned by the iterator. "<this>" is inserted when the collection
* contains itself (only works for direct containment, not for collections
* inside collections).
*
* @return a String representation of the Collection
*/
@ -431,10 +433,16 @@ public abstract class AbstractCollection implements Collection
{
Iterator itr = iterator();
StringBuffer r = new StringBuffer("[");
for (int pos = size(); pos > 0; pos--)
boolean hasNext = itr.hasNext();
while (hasNext)
{
r.append(itr.next());
if (pos > 1)
Object o = itr.next();
if (o == this)
r.append("<this>");
else
r.append(o);
hasNext = itr.hasNext();
if (hasNext)
r.append(", ");
}
r.append("]");

View file

@ -1,5 +1,5 @@
/* ResourceBundle -- aids in loading resource bundles
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -476,9 +476,7 @@ public abstract class ResourceBundle
if (ResourceBundle.class.isAssignableFrom(rbClass))
bundle = (ResourceBundle) rbClass.newInstance();
}
catch (IllegalAccessException ex) {}
catch (InstantiationException ex) {}
catch (ClassNotFoundException ex) {}
catch (Exception ex) {}
if (bundle == null)
{

View file

@ -427,16 +427,13 @@ public class Attributes implements Cloneable, Map
* Attributes map.
* When the name already exists the value is replaced and the old value
* is returned.
* <p>
* I don't know why there is no public method with this signature. I think
* there should be one.
*
* @param name the attribite name to add/replace
* @param value the (new) value of the attribute name
* @returns the old value of the attribute name or null if it didn't exist
* yet
*/
String putValue(Name name, String value)
public String putValue(Name name, String value)
{
return (String) put(name, value);
}

View file

@ -115,7 +115,7 @@ import java.util.ListIterator;
*
* <li><code>%h</code> - replaced by the location of the home
* directory of the current user. This value is taken from the
* system property <code>file.separator</code>.</li>
* system property <code>user.home</code>.</li>
*
* <li><code>%g</code> - replaced by a generation number for
* distinguisthing the individual items in the rotating set

View file

@ -41,6 +41,7 @@ package java.util.logging;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
@ -295,6 +296,28 @@ public class LogManager
if (parent != logger.getParent())
logger.setParent(parent);
// The level of the newly added logger must be specified.
// The easiest case is if there is a level for exactly this logger
// in the properties. If no such level exists the level needs to be
// searched along the hirachy. So if there is a new logger 'foo.blah.blub'
// and an existing parent logger 'foo' the properties 'foo.blah.blub.level'
// and 'foo.blah.level' need to be checked. If both do not exist in the
// properties the level of the new logger is set to 'null' (i.e. it uses the
// level of its parent 'foo').
Level logLevel = logger.getLevel();
String searchName = name;
String parentName = parent != null ? parent.getName() : "";
while (logLevel == null && ! searchName.equals(parentName))
{
logLevel = getLevelProperty(searchName + ".level", logLevel);
int index = searchName.lastIndexOf('.');
if(index > -1)
searchName = searchName.substring(0,index);
else
searchName = "";
}
logger.setLevel(logLevel);
/* It can happen that existing loggers should be children of
* the newly added logger. For example, assume that there
* already exist loggers under the names "", "foo", and "foo.bar.baz".
@ -488,23 +511,37 @@ public class LogManager
path = System.getProperty("java.util.logging.config.file");
if ((path == null) || (path.length() == 0))
{
String url = (System.getProperty("gnu.classpath.home.url")
+ "/logging.properties");
inputStream = new URL(url).openStream();
String url = (System.getProperty("gnu.classpath.home.url")
+ "/logging.properties");
try
{
inputStream = new URL(url).openStream();
}
catch (Exception e)
{
inputStream=null;
}
// If no config file could be found use a default configuration.
if(inputStream == null)
{
String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n"
+ ".level=INFO \n";
inputStream = new ByteArrayInputStream(defaultConfig.getBytes());
}
}
else
inputStream = new java.io.FileInputStream(path);
try
{
readConfiguration(inputStream);
readConfiguration(inputStream);
}
finally
{
/* Close the stream in order to save
* resources such as file descriptors.
*/
inputStream.close();
// Close the stream in order to save
// resources such as file descriptors.
inputStream.close();
}
}

View file

@ -39,6 +39,8 @@ exception statement from your version. */
package java.util.logging;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.util.Date;
@ -114,6 +116,14 @@ public class SimpleFormatter
buf.append(lineSep);
Throwable throwable = record.getThrown();
if (throwable != null)
{
StringWriter sink = new StringWriter();
throwable.printStackTrace(new PrintWriter(sink, true));
buf.append(sink.toString());
}
return buf.toString();
}
}

View file

@ -1,5 +1,5 @@
/* AbstractPreferences -- Partial implementation of a Preference node
Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -38,11 +38,13 @@ exception statement from your version. */
package java.util.prefs;
import gnu.java.util.prefs.EventDispatcher;
import gnu.java.util.prefs.NodeWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
@ -68,7 +70,7 @@ public abstract class AbstractPreferences extends Preferences {
/**
* Set to true in the contructor if the node did not exist in the backing
* store when this preference node object was created. Should be set in
* the contructor of a subclass. Defaults to false. Used to fire node
* the constructor of a subclass. Defaults to false. Used to fire node
* changed events.
*/
protected boolean newNode = false;
@ -97,6 +99,16 @@ public abstract class AbstractPreferences extends Preferences {
*/
private HashMap childCache = new HashMap();
/**
* A list of all the registered NodeChangeListener objects.
*/
private ArrayList nodeListeners;
/**
* A list of all the registered PreferenceChangeListener objects.
*/
private ArrayList preferenceListeners;
// constructor
/**
@ -256,7 +268,7 @@ public abstract class AbstractPreferences extends Preferences {
* @exception IllegalArgumentException if the path contains two or more
* consecutive '/' characters, ends with a '/' charactor and is not the
* string "/" (indicating the root node) or any name on the path is more
* then 80 characters long
* than 80 characters long
*/
public Preferences node(String path) {
synchronized(lock) {
@ -325,8 +337,9 @@ public abstract class AbstractPreferences extends Preferences {
// Not in childCache yet so create a new sub node
child = childSpi(childName);
// XXX - check if node is new
childCache.put(childName, child);
if (child.newNode && nodeListeners != null)
fire(new NodeChangeEvent(this, child), true);
}
// Lock the child and go down
@ -477,9 +490,7 @@ public abstract class AbstractPreferences extends Preferences {
// export methods
/**
* XXX
*/
// Inherit javadoc.
public void exportNode(OutputStream os)
throws BackingStoreException,
IOException
@ -488,9 +499,7 @@ public abstract class AbstractPreferences extends Preferences {
nodeWriter.writePrefs();
}
/**
* XXX
*/
// Inherit javadoc.
public void exportSubtree(OutputStream os)
throws BackingStoreException,
IOException
@ -765,8 +774,8 @@ public abstract class AbstractPreferences extends Preferences {
* Key and value cannot be null, the key cannot exceed 80 characters
* and the value cannot exceed 8192 characters.
* <p>
* The result will be immediatly visible in this VM, but may not be
* immediatly written to the backing store.
* The result will be immediately visible in this VM, but may not be
* immediately written to the backing store.
* <p>
* Checks that key and value are valid, locks this node, and checks that
* the node has not been removed. Then it calls <code>putSpi()</code>.
@ -789,7 +798,8 @@ public abstract class AbstractPreferences extends Preferences {
putSpi(key, value);
// XXX - fire events
if (preferenceListeners != null)
fire(new PreferenceChangeEvent(this, key, value));
}
}
@ -804,9 +814,7 @@ public abstract class AbstractPreferences extends Preferences {
* @exception IllegalStateException when this node has been removed
*/
public void putBoolean(String key, boolean value) {
put(key, String.valueOf(value));
// XXX - Use when using 1.4 compatible Boolean
// put(key, Boolean.toString(value));
put(key, Boolean.toString(value));
}
/**
@ -935,8 +943,8 @@ public abstract class AbstractPreferences extends Preferences {
/**
* Removes the preferences entry from this preferences node.
* <p>
* The result will be immediatly visible in this VM, but may not be
* immediatly written to the backing store.
* The result will be immediately visible in this VM, but may not be
* immediately written to the backing store.
* <p>
* This implementation checks that the key is not larger then 80
* characters, gets the lock of this node, checks that the node has
@ -955,6 +963,9 @@ public abstract class AbstractPreferences extends Preferences {
throw new IllegalStateException("Node removed");
removeSpi(key);
if (preferenceListeners != null)
fire(new PreferenceChangeEvent(this, key, null));
}
}
@ -962,7 +973,7 @@ public abstract class AbstractPreferences extends Preferences {
* Removes all entries from this preferences node. May need access to the
* backing store to get and clear all entries.
* <p>
* The result will be immediatly visible in this VM, but may not be
* The result will be immediately visible in this VM, but may not be
* immediatly written to the backing store.
* <p>
* This implementation locks this node, checks that the node has not been
@ -1049,7 +1060,7 @@ public abstract class AbstractPreferences extends Preferences {
for (int i = 0; i < keys.length; i++) {
// Have to lock this node again to access the childCache
AbstractPreferences subNode;
synchronized(this) {
synchronized(lock) {
subNode = (AbstractPreferences) childCache.get(keys[i]);
}
@ -1087,8 +1098,8 @@ public abstract class AbstractPreferences extends Preferences {
if (parent == null)
throw new UnsupportedOperationException("Cannot remove root node");
synchronized(parent) {
synchronized(this) {
synchronized (parent.lock) {
synchronized(this.lock) {
if (isRemoved())
throw new IllegalStateException("Node Removed");
@ -1122,7 +1133,7 @@ public abstract class AbstractPreferences extends Preferences {
Iterator i = childCache.values().iterator();
while (i.hasNext()) {
AbstractPreferences node = (AbstractPreferences) i.next();
synchronized(node) {
synchronized(node.lock) {
node.purge();
}
}
@ -1134,30 +1145,131 @@ public abstract class AbstractPreferences extends Preferences {
removeNodeSpi();
removed = true;
// XXX - check for listeners
if (nodeListeners != null)
fire(new NodeChangeEvent(parent, this), false);
}
// listener methods
/**
* XXX
* Add a listener which is notified when a sub-node of this node
* is added or removed.
* @param listener the listener to add
*/
public void addNodeChangeListener(NodeChangeListener listener) {
// XXX
}
public void addPreferenceChangeListener(PreferenceChangeListener listener) {
// XXX
}
public void removeNodeChangeListener(NodeChangeListener listener) {
// XXX
}
public void removePreferenceChangeListener
(PreferenceChangeListener listener)
public void addNodeChangeListener(NodeChangeListener listener)
{
// XXX
synchronized (lock)
{
if (isRemoved())
throw new IllegalStateException("node has been removed");
if (listener == null)
throw new NullPointerException("listener is null");
if (nodeListeners == null)
nodeListeners = new ArrayList();
nodeListeners.add(listener);
}
}
/**
* Add a listener which is notified when a value in this node
* is added, changed, or removed.
* @param listener the listener to add
*/
public void addPreferenceChangeListener(PreferenceChangeListener listener)
{
synchronized (lock)
{
if (isRemoved())
throw new IllegalStateException("node has been removed");
if (listener == null)
throw new NullPointerException("listener is null");
if (preferenceListeners == null)
preferenceListeners = new ArrayList();
preferenceListeners.add(listener);
}
}
/**
* Remove the indicated node change listener from the list of
* listeners to notify.
* @param listener the listener to remove
*/
public void removeNodeChangeListener(NodeChangeListener listener)
{
synchronized (lock)
{
if (isRemoved())
throw new IllegalStateException("node has been removed");
if (listener == null)
throw new NullPointerException("listener is null");
if (nodeListeners != null)
nodeListeners.remove(listener);
}
}
/**
* Remove the indicated preference change listener from the list of
* listeners to notify.
* @param listener the listener to remove
*/
public void removePreferenceChangeListener (PreferenceChangeListener listener)
{
synchronized (lock)
{
if (isRemoved())
throw new IllegalStateException("node has been removed");
if (listener == null)
throw new NullPointerException("listener is null");
if (preferenceListeners != null)
preferenceListeners.remove(listener);
}
}
/**
* Send a preference change event to all listeners. Note that
* the caller is responsible for holding the node's lock, and
* for checking that the list of listeners is not null.
* @param event the event to send
*/
private void fire(final PreferenceChangeEvent event)
{
Iterator it = preferenceListeners.iterator();
while (it.hasNext())
{
final PreferenceChangeListener l = (PreferenceChangeListener) it.next();
EventDispatcher.dispatch(new Runnable()
{
public void run()
{
l.preferenceChange(event);
}
});
}
}
/**
* Send a node change event to all listeners. Note that
* the caller is responsible for holding the node's lock, and
* for checking that the list of listeners is not null.
* @param event the event to send
*/
private void fire(final NodeChangeEvent event, final boolean added)
{
Iterator it = nodeListeners.iterator();
while (it.hasNext())
{
final NodeChangeListener l = (NodeChangeListener) it.next();
EventDispatcher.dispatch(new Runnable()
{
public void run()
{
if (added)
l.childAdded(event);
else
l.childRemoved(event);
}
});
}
}
// abstract spi methods
@ -1214,7 +1326,7 @@ public abstract class AbstractPreferences extends Preferences {
/**
* Sets the value of the given preferences entry for this node.
* The implementation is not required to propagate the change to the
* backing store immediatly. It may not throw an exception when it tries
* backing store immediately. It may not throw an exception when it tries
* to write to the backing store and that operation fails, the failure
* should be registered so a later invocation of <code>flush()</code>
* or <code>sync()</code> can signal the failure.
@ -1227,7 +1339,7 @@ public abstract class AbstractPreferences extends Preferences {
/**
* Removes the given key entry from this preferences node.
* The implementation is not required to propagate the change to the
* backing store immediatly. It may not throw an exception when it tries
* backing store immediately. It may not throw an exception when it tries
* to write to the backing store and that operation fails, the failure
* should be registered so a later invocation of <code>flush()</code>
* or <code>sync()</code> can signal the failure.

View file

@ -1,5 +1,5 @@
/* NodeChangeEvent - ObjectEvent fired when a Preference node is added/removed
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -37,6 +37,10 @@ exception statement from your version. */
package java.util.prefs;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventObject;
/**
@ -44,12 +48,16 @@ import java.util.EventObject;
* This event is only generated when a new subnode is added or a subnode is
* removed from a preference node. Changes in the entries of a preference node
* are indicated with a <code>PreferenceChangeEvent</code>.
* <p>
* Note that although this class is marked as serializable, attempts to
* serialize it will fail with NotSerializableException.
*
* @since 1.4
* @author Mark Wielaard (mark@klomp.org)
*/
public class NodeChangeEvent extends EventObject {
// We have this to placate the compiler.
private static final long serialVersionUID =8068949086596572957L;
/**
@ -88,4 +96,16 @@ public class NodeChangeEvent extends EventObject {
public Preferences getChild() {
return child;
}
private void readObject(ObjectInputStream ois)
throws IOException
{
throw new NotSerializableException("LineEvent is not serializable");
}
private void writeObject(ObjectOutputStream oos)
throws IOException
{
throw new NotSerializableException("LineEvent is not serializable");
}
}

View file

@ -1,5 +1,5 @@
/* PreferenceChangeEvent - ObjectEvent fired when a Preferences entry changes
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -37,6 +37,10 @@ exception statement from your version. */
package java.util.prefs;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventObject;
/**
@ -47,12 +51,16 @@ import java.util.EventObject;
* Preference change events are only generated for entries in one particular
* preference node. Notification of subnode addition/removal is given by a
* <code>NodeChangeEvent</code>.
* <p>
* Note that although this class is marked as serializable, attempts to
* serialize it will fail with NotSerializableException.
*
* @since 1.4
* @author Mark Wielaard (mark@klomp.org)
*/
public class PreferenceChangeEvent extends EventObject {
// We have this to placate the compiler.
private static final long serialVersionUID = 793724513368024975L;
/**
@ -102,4 +110,16 @@ public class PreferenceChangeEvent extends EventObject {
public String getNewValue() {
return newValue;
}
private void readObject(ObjectInputStream ois)
throws IOException
{
throw new NotSerializableException("LineEvent is not serializable");
}
private void writeObject(ObjectOutputStream oos)
throws IOException
{
throw new NotSerializableException("LineEvent is not serializable");
}
}

View file

@ -1,5 +1,5 @@
/* Preferences -- Preference node containing key value entries and subnodes
Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -90,12 +90,9 @@ public abstract class Preferences {
/**
* Default PreferencesFactory class used when the system property
* "java.util.prefs.PreferencesFactory" is not set.
* <p>
* XXX - Currently set to MemoryBasedFactory, should be changed
* when FileBasedPreferences backend works.
*/
private static final String defaultFactoryClass
= "gnu.java.util.prefs.MemoryBasedFactory";
= "gnu.java.util.prefs.FileBasedFactory";
/** Permission needed to access system or user root. */
private static final Permission prefsPermission
@ -219,8 +216,7 @@ public abstract class Preferences {
catch (Exception e)
{
throw new RuntimeException ("Couldn't load default factory"
+ " '"+ defaultFactoryClass +"'");
// XXX - when using 1.4 compatible throwables add cause
+ " '"+ defaultFactoryClass +"'", e);
}
}
@ -288,7 +284,13 @@ public abstract class Preferences {
}
/**
* XXX
* Import preferences from the given input stream. This expects
* preferences to be represented in XML as emitted by
* {@link #exportNode(OutputStream)} and
* {@link #exportSubtree(OutputStream)}.
* @throws IOException if there is an error while reading
* @throws InvalidPreferencesFormatException if the XML is not properly
* formatted
*/
public static void importPreferences(InputStream is)
throws InvalidPreferencesFormatException,
@ -385,14 +387,28 @@ public abstract class Preferences {
// abstract methods (export)
/**
* XXX
* Export this node, but not its descendants, as XML to the
* indicated output stream. The XML will be encoded using UTF-8
* and will use a specified document type:<br>
* <code>&lt;!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"&gt;</code><br>
* @param os the output stream to which the XML is sent
* @throws BackingStoreException if preference data cannot be read
* @throws IOException if an error occurs while writing the XML
* @throws IllegalStateException if this node or an ancestor has been removed
*/
public abstract void exportNode(OutputStream os)
throws BackingStoreException,
IOException;
/**
* XXX
* Export this node and all its descendants as XML to the
* indicated output stream. The XML will be encoded using UTF-8
* and will use a specified document type:<br>
* <code>&lt;!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"&gt;</code><br>
* @param os the output stream to which the XML is sent
* @throws BackingStoreException if preference data cannot be read
* @throws IOException if an error occurs while writing the XML
* @throws IllegalStateException if this node or an ancestor has been removed
*/
public abstract void exportSubtree(OutputStream os)
throws BackingStoreException,

View file

@ -0,0 +1,81 @@
/* MatchResult.java -- Result of a regular expression match.
Copyright (C) 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.util.regex;
/**
* This interface represents the result of a regular expression match.
* It can be used to query the contents of the match, but not to modify
* them.
* @since 1.5
*/
public interface MatchResult
{
/** Returns the index just after the last matched character. */
int end();
/**
* Returns the index just after the last matched character of the
* given sub-match group.
* @param group the sub-match group
*/
int end(int group);
/** Returns the substring of the input which was matched. */
String group();
/**
* Returns the substring of the input which was matched by the
* given sub-match group.
* @param group the sub-match group
*/
String group(int group);
/** Returns the number of sub-match groups in the matching pattern. */
int groupCount();
/** Returns the index of the first character of the match. */
int start();
/**
* Returns the index of the first character of the given sub-match
* group.
* @param group the sub-match group
*/
int start(int group);
}

View file

@ -1,5 +1,5 @@
/* Matcher.java -- Instance of a regular expression applied to a char sequence.
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -38,6 +38,7 @@ exception statement from your version. */
package java.util.regex;
import gnu.regexp.RE;
import gnu.regexp.REMatch;
/**
@ -45,7 +46,7 @@ import gnu.regexp.REMatch;
*
* @since 1.4
*/
public final class Matcher
public final class Matcher implements MatchResult
{
private Pattern pattern;
private CharSequence input;
@ -74,7 +75,8 @@ public final class Matcher
assertMatchOp();
sb.append(input.subSequence(appendPosition,
match.getStartIndex()).toString());
sb.append(match.substituteInto(replacement));
sb.append(RE.getReplacement(replacement, match,
RE.REG_REPLACE_USE_BACKSLASHESCAPE));
appendPosition = match.getEndIndex();
return this;
}
@ -189,7 +191,8 @@ public final class Matcher
{
reset();
// Semantics might not quite match
return pattern.getRE().substitute(input, replacement, position);
return pattern.getRE().substitute(input, replacement, position,
RE.REG_REPLACE_USE_BACKSLASHESCAPE);
}
/**
@ -198,7 +201,8 @@ public final class Matcher
public String replaceAll (String replacement)
{
reset();
return pattern.getRE().substituteAll(input, replacement, position);
return pattern.getRE().substituteAll(input, replacement, position,
RE.REG_REPLACE_USE_BACKSLASHESCAPE);
}
public int groupCount ()
@ -233,10 +237,15 @@ public final class Matcher
*/
public boolean matches ()
{
if (lookingAt())
match = pattern.getRE().getMatch(input, 0, RE.REG_TRY_ENTIRE_MATCH);
if (match != null)
{
if (position == input.length())
return true;
if (match.getStartIndex() == 0)
{
position = match.getEndIndex();
if (position == input.length())
return true;
}
match = null;
}
return false;

View file

@ -41,6 +41,7 @@ package java.util.regex;
* Indicates illegal pattern for regular expression.
* Includes state to inspect the pattern and what and where the expression
* was not valid regular expression.
* @since 1.4
*/
public class PatternSyntaxException extends IllegalArgumentException
{

View file

@ -1,5 +1,5 @@
/* java.util.zip.ZipConstants
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -41,7 +41,7 @@ interface ZipConstants
{
/* The local file header */
int LOCHDR = 30;
int LOCSIG = 'P'|('K'<<8)|(3<<16)|(4<<24);
long LOCSIG = 'P'|('K'<<8)|(3<<16)|(4<<24);
int LOCVER = 4;
int LOCFLG = 6;
@ -54,7 +54,7 @@ interface ZipConstants
int LOCEXT = 28;
/* The Data descriptor */
int EXTSIG = 'P'|('K'<<8)|(7<<16)|(8<<24);
long EXTSIG = 'P'|('K'<<8)|(7<<16)|(8<<24);
int EXTHDR = 16;
int EXTCRC = 4;
@ -62,7 +62,7 @@ interface ZipConstants
int EXTLEN = 12;
/* The central directory file header */
int CENSIG = 'P'|('K'<<8)|(1<<16)|(2<<24);
long CENSIG = 'P'|('K'<<8)|(1<<16)|(2<<24);
int CENHDR = 46;
int CENVEM = 4;
@ -82,7 +82,7 @@ interface ZipConstants
int CENOFF = 42;
/* The entries in the end of central directory */
int ENDSIG = 'P'|('K'<<8)|(5<<16)|(6<<24);
long ENDSIG = 'P'|('K'<<8)|(5<<16)|(6<<24);
int ENDHDR = 22;
/* The following two fields are missing in SUN JDK */

View file

@ -1,5 +1,5 @@
/* ZipFile.java --
Copyright (C) 2001, 2002, 2003, 2004, 2005
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -41,8 +41,6 @@ package java.util.zip;
import gnu.java.util.EmptyEnumeration;
import java.io.BufferedInputStream;
import java.io.DataInput;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
@ -141,23 +139,33 @@ public class ZipFile implements ZipConstants
checkZipFile();
}
private void checkZipFile() throws IOException, ZipException
private void checkZipFile() throws ZipException
{
byte[] magicBuf = new byte[4];
boolean validRead = true;
boolean valid = false;
try
{
raf.readFully(magicBuf);
}
catch (EOFException eof)
byte[] buf = new byte[4];
raf.readFully(buf);
int sig = buf[0] & 0xFF
| ((buf[1] & 0xFF) << 8)
| ((buf[2] & 0xFF) << 16)
| ((buf[3] & 0xFF) << 24);
valid = sig == LOCSIG;
}
catch (IOException _)
{
validRead = false;
}
if (validRead == false || readLeInt(magicBuf, 0) != LOCSIG)
if (!valid)
{
raf.close();
try
{
raf.close();
}
catch (IOException _)
{
}
throw new ZipException("Not a valid zip file");
}
}
@ -171,69 +179,6 @@ public class ZipFile implements ZipConstants
throw new IllegalStateException("ZipFile has closed: " + name);
}
/**
* Read an unsigned short in little endian byte order from the given
* DataInput stream using the given byte buffer.
*
* @param di DataInput stream to read from.
* @param b the byte buffer to read in (must be at least 2 bytes long).
* @return The value read.
*
* @exception IOException if a i/o error occured.
* @exception EOFException if the file ends prematurely
*/
private int readLeShort(DataInput di, byte[] b) throws IOException
{
di.readFully(b, 0, 2);
return (b[0] & 0xff) | (b[1] & 0xff) << 8;
}
/**
* Read an int in little endian byte order from the given
* DataInput stream using the given byte buffer.
*
* @param di DataInput stream to read from.
* @param b the byte buffer to read in (must be at least 4 bytes long).
* @return The value read.
*
* @exception IOException if a i/o error occured.
* @exception EOFException if the file ends prematurely
*/
private int readLeInt(DataInput di, byte[] b) throws IOException
{
di.readFully(b, 0, 4);
return ((b[0] & 0xff) | (b[1] & 0xff) << 8)
| ((b[2] & 0xff) | (b[3] & 0xff) << 8) << 16;
}
/**
* Read an unsigned short in little endian byte order from the given
* byte buffer at the given offset.
*
* @param b the byte array to read from.
* @param off the offset to read from.
* @return The value read.
*/
private int readLeShort(byte[] b, int off)
{
return (b[off] & 0xff) | (b[off+1] & 0xff) << 8;
}
/**
* Read an int in little endian byte order from the given
* byte buffer at the given offset.
*
* @param b the byte array to read from.
* @param off the offset to read from.
* @return The value read.
*/
private int readLeInt(byte[] b, int off)
{
return ((b[off] & 0xff) | (b[off+1] & 0xff) << 8)
| ((b[off+2] & 0xff) | (b[off+3] & 0xff) << 8) << 16;
}
/**
* Read the central directory of a zip file and fill the entries
* array. This is called exactly once when first needed. It is called
@ -246,63 +191,48 @@ public class ZipFile implements ZipConstants
{
/* Search for the End Of Central Directory. When a zip comment is
* present the directory may start earlier.
* FIXME: This searches the whole file in a very slow manner if the
* file isn't a zip file.
* Note that a comment has a maximum length of 64K, so that is the
* maximum we search backwards.
*/
PartialInputStream inp = new PartialInputStream(raf, 4096);
long pos = raf.length() - ENDHDR;
byte[] ebs = new byte[CENHDR];
long top = Math.max(0, pos - 65536);
do
{
if (pos < 0)
if (pos < top)
throw new ZipException
("central directory not found, probably not a zip file: " + name);
raf.seek(pos--);
inp.seek(pos--);
}
while (readLeInt(raf, ebs) != ENDSIG);
while (inp.readLeInt() != ENDSIG);
if (raf.skipBytes(ENDTOT - ENDNRD) != ENDTOT - ENDNRD)
if (inp.skip(ENDTOT - ENDNRD) != ENDTOT - ENDNRD)
throw new EOFException(name);
int count = readLeShort(raf, ebs);
if (raf.skipBytes(ENDOFF - ENDSIZ) != ENDOFF - ENDSIZ)
int count = inp.readLeShort();
if (inp.skip(ENDOFF - ENDSIZ) != ENDOFF - ENDSIZ)
throw new EOFException(name);
int centralOffset = readLeInt(raf, ebs);
int centralOffset = inp.readLeInt();
entries = new HashMap(count+count/2);
raf.seek(centralOffset);
inp.seek(centralOffset);
byte[] buffer = new byte[16];
for (int i = 0; i < count; i++)
{
raf.readFully(ebs);
if (readLeInt(ebs, 0) != CENSIG)
if (inp.readLeInt() != CENSIG)
throw new ZipException("Wrong Central Directory signature: " + name);
int method = readLeShort(ebs, CENHOW);
int dostime = readLeInt(ebs, CENTIM);
int crc = readLeInt(ebs, CENCRC);
int csize = readLeInt(ebs, CENSIZ);
int size = readLeInt(ebs, CENLEN);
int nameLen = readLeShort(ebs, CENNAM);
int extraLen = readLeShort(ebs, CENEXT);
int commentLen = readLeShort(ebs, CENCOM);
int offset = readLeInt(ebs, CENOFF);
int needBuffer = Math.max(nameLen, commentLen);
if (buffer.length < needBuffer)
buffer = new byte[needBuffer];
raf.readFully(buffer, 0, nameLen);
String name;
try
{
name = new String(buffer, 0, nameLen, "UTF-8");
}
catch (UnsupportedEncodingException uee)
{
throw new AssertionError(uee);
}
inp.skip(6);
int method = inp.readLeShort();
int dostime = inp.readLeInt();
int crc = inp.readLeInt();
int csize = inp.readLeInt();
int size = inp.readLeInt();
int nameLen = inp.readLeShort();
int extraLen = inp.readLeShort();
int commentLen = inp.readLeShort();
inp.skip(8);
int offset = inp.readLeInt();
String name = inp.readString(nameLen);
ZipEntry entry = new ZipEntry(name);
entry.setMethod(method);
@ -313,20 +243,12 @@ public class ZipFile implements ZipConstants
if (extraLen > 0)
{
byte[] extra = new byte[extraLen];
raf.readFully(extra);
inp.readFully(extra);
entry.setExtra(extra);
}
if (commentLen > 0)
{
raf.readFully(buffer, 0, commentLen);
try
{
entry.setComment(new String(buffer, 0, commentLen, "UTF-8"));
}
catch (UnsupportedEncodingException uee)
{
throw new AssertionError(uee);
}
entry.setComment(inp.readString(commentLen));
}
entry.offset = offset;
entries.put(name, entry);
@ -429,42 +351,6 @@ public class ZipFile implements ZipConstants
}
}
//access should be protected by synchronized(raf)
private byte[] locBuf = new byte[LOCHDR];
/**
* Checks, if the local header of the entry at index i matches the
* central directory, and returns the offset to the data.
*
* @param entry to check.
* @return the start offset of the (compressed) data.
*
* @exception IOException if a i/o error occured.
* @exception ZipException if the local header doesn't match the
* central directory header
*/
private long checkLocalHeader(ZipEntry entry) throws IOException
{
synchronized (raf)
{
raf.seek(entry.offset);
raf.readFully(locBuf);
if (readLeInt(locBuf, 0) != LOCSIG)
throw new ZipException("Wrong Local header signature: " + name);
if (entry.getMethod() != readLeShort(locBuf, LOCHOW))
throw new ZipException("Compression method mismatch: " + name);
if (entry.getName().length() != readLeShort(locBuf, LOCNAM))
throw new ZipException("file name length mismatch: " + name);
int extraLen = entry.getName().length() + readLeShort(locBuf, LOCEXT);
return entry.offset + LOCHDR + extraLen;
}
}
/**
* Creates an input stream reading the given zip entry as
* uncompressed data. Normally zip entry should be an entry
@ -497,16 +383,32 @@ public class ZipFile implements ZipConstants
if (zipEntry == null)
return null;
long start = checkLocalHeader(zipEntry);
PartialInputStream inp = new PartialInputStream(raf, 1024);
inp.seek(zipEntry.offset);
if (inp.readLeInt() != LOCSIG)
throw new ZipException("Wrong Local header signature: " + name);
inp.skip(4);
if (zipEntry.getMethod() != inp.readLeShort())
throw new ZipException("Compression method mismatch: " + name);
inp.skip(16);
int nameLen = inp.readLeShort();
int extraLen = inp.readLeShort();
inp.skip(nameLen + extraLen);
inp.setLength(zipEntry.getCompressedSize());
int method = zipEntry.getMethod();
InputStream is = new BufferedInputStream(new PartialInputStream
(raf, start, zipEntry.getCompressedSize()));
switch (method)
{
case ZipOutputStream.STORED:
return is;
return inp;
case ZipOutputStream.DEFLATED:
return new InflaterInputStream(is, new Inflater(true));
return new InflaterInputStream(inp, new Inflater(true));
default:
throw new ZipException("Unknown compression method " + method);
}
@ -562,21 +464,41 @@ public class ZipFile implements ZipConstants
}
}
private static class PartialInputStream extends InputStream
private static final class PartialInputStream extends InputStream
{
private final RandomAccessFile raf;
long filepos, end;
private final byte[] buffer;
private long bufferOffset;
private int pos;
private long end;
public PartialInputStream(RandomAccessFile raf, long start, long len)
public PartialInputStream(RandomAccessFile raf, int bufferSize)
throws IOException
{
this.raf = raf;
filepos = start;
end = start + len;
buffer = new byte[bufferSize];
bufferOffset = -buffer.length;
pos = buffer.length;
end = raf.length();
}
void setLength(long length)
{
end = bufferOffset + pos + length;
}
private void fillBuffer() throws IOException
{
synchronized (raf)
{
raf.seek(bufferOffset);
raf.readFully(buffer, 0, (int) Math.min(buffer.length, end - bufferOffset));
}
}
public int available()
{
long amount = end - filepos;
long amount = end - (bufferOffset + pos);
if (amount > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int) amount;
@ -584,41 +506,130 @@ public class ZipFile implements ZipConstants
public int read() throws IOException
{
if (filepos == end)
if (bufferOffset + pos >= end)
return -1;
synchronized (raf)
{
raf.seek(filepos++);
return raf.read();
}
if (pos == buffer.length)
{
bufferOffset += buffer.length;
pos = 0;
fillBuffer();
}
return buffer[pos++] & 0xFF;
}
public int read(byte[] b, int off, int len) throws IOException
{
if (len > end - filepos)
if (len > end - (bufferOffset + pos))
{
len = (int) (end - filepos);
len = (int) (end - (bufferOffset + pos));
if (len == 0)
return -1;
}
synchronized (raf)
{
raf.seek(filepos);
int count = raf.read(b, off, len);
if (count > 0)
filepos += len;
return count;
}
int totalBytesRead = Math.min(buffer.length - pos, len);
System.arraycopy(buffer, pos, b, off, totalBytesRead);
pos += totalBytesRead;
off += totalBytesRead;
len -= totalBytesRead;
while (len > 0)
{
bufferOffset += buffer.length;
pos = 0;
fillBuffer();
int remain = Math.min(buffer.length, len);
System.arraycopy(buffer, pos, b, off, remain);
pos += remain;
off += remain;
len -= remain;
totalBytesRead += remain;
}
return totalBytesRead;
}
public long skip(long amount)
public long skip(long amount) throws IOException
{
if (amount < 0)
throw new IllegalArgumentException();
if (amount > end - filepos)
amount = end - filepos;
filepos += amount;
return 0;
if (amount > end - (bufferOffset + pos))
amount = end - (bufferOffset + pos);
seek(bufferOffset + pos + amount);
return amount;
}
void seek(long newpos) throws IOException
{
long offset = newpos - bufferOffset;
if (offset >= 0 && offset <= buffer.length)
{
pos = (int) offset;
}
else
{
bufferOffset = newpos;
pos = 0;
fillBuffer();
}
}
void readFully(byte[] buf) throws IOException
{
if (read(buf, 0, buf.length) != buf.length)
throw new EOFException();
}
void readFully(byte[] buf, int off, int len) throws IOException
{
if (read(buf, off, len) != len)
throw new EOFException();
}
int readLeShort() throws IOException
{
int b0 = read();
int b1 = read();
if (b1 == -1)
throw new EOFException();
return (b0 & 0xff) | (b1 & 0xff) << 8;
}
int readLeInt() throws IOException
{
int b0 = read();
int b1 = read();
int b2 = read();
int b3 = read();
if (b3 == -1)
throw new EOFException();
return ((b0 & 0xff) | (b1 & 0xff) << 8)
| ((b2 & 0xff) | (b3 & 0xff) << 8) << 16;
}
String readString(int length) throws IOException
{
if (length > end - (bufferOffset + pos))
throw new EOFException();
try
{
if (buffer.length - pos >= length)
{
String s = new String(buffer, pos, length, "UTF-8");
pos += length;
return s;
}
else
{
byte[] b = new byte[length];
readFully(b);
return new String(b, 0, length, "UTF-8");
}
}
catch (UnsupportedEncodingException uee)
{
throw new AssertionError(uee);
}
}
}
}

View file

@ -1,5 +1,5 @@
/* ZipOutputStream.java --
Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -160,6 +160,16 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
writeLeShort(value >> 16);
}
/**
* Write a long value as an int. Some of the zip constants
* are declared as longs even though they fit perfectly well
* into integers.
*/
private void writeLeInt(long value) throws IOException
{
writeLeInt((int) value);
}
/**
* Starts a new Zip entry. It automatically closes the previous
* entry if present. If the compression method is stored, the entry