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:
parent
27079765d0
commit
8aa540d2f7
1367 changed files with 188789 additions and 22762 deletions
|
@ -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("]");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"></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><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"></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,
|
||||
|
|
81
libjava/classpath/java/util/regex/MatchResult.java
Normal file
81
libjava/classpath/java/util/regex/MatchResult.java
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue