merge with trunk arithmetic
authorMartin Soch <Martin.Soch@oracle.com>
Tue, 05 Feb 2013 17:04:22 +0100
brancharithmetic
changeset 6771ff540c1650f
parent 676 eecf6077ec4e
parent 668 b4354a30d4dd
child 678 8a25056ef283
merge with trunk
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/MethodInvocation.java
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java
     1.1 --- a/core/pom.xml	Tue Feb 05 16:40:01 2013 +0100
     1.2 +++ b/core/pom.xml	Tue Feb 05 17:04:22 2013 +0100
     1.3 @@ -38,6 +38,7 @@
     1.4      <dependency>
     1.5        <groupId>org.netbeans.api</groupId>
     1.6        <artifactId>org-openide-util-lookup</artifactId>
     1.7 +      <scope>provided</scope>
     1.8      </dependency>
     1.9    </dependencies>
    1.10      <description>Contains esential annotations for associating JavaScript code with
     2.1 --- a/emul/compact/pom.xml	Tue Feb 05 16:40:01 2013 +0100
     2.2 +++ b/emul/compact/pom.xml	Tue Feb 05 17:04:22 2013 +0100
     2.3 @@ -27,6 +27,11 @@
     2.4        <version>${project.version}</version>
     2.5        <scope>test</scope>
     2.6      </dependency>
     2.7 +    <dependency>
     2.8 +      <groupId>org.netbeans.api</groupId>
     2.9 +      <artifactId>org-openide-util-lookup</artifactId>
    2.10 +      <scope>test</scope>
    2.11 +    </dependency>
    2.12    </dependencies>
    2.13    <build>
    2.14        <plugins>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/emul/compact/src/main/java/java/beans/ChangeListenerMap.java	Tue Feb 05 17:04:22 2013 +0100
     3.3 @@ -0,0 +1,248 @@
     3.4 +/*
     3.5 + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.  Oracle designates this
    3.11 + * particular file as subject to the "Classpath" exception as provided
    3.12 + * by Oracle in the LICENSE file that accompanied this code.
    3.13 + *
    3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 + * version 2 for more details (a copy is included in the LICENSE file that
    3.18 + * accompanied this code).
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License version
    3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.23 + *
    3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.25 + * or visit www.oracle.com if you need additional information or have any
    3.26 + * questions.
    3.27 + */
    3.28 +package java.beans;
    3.29 +
    3.30 +import java.util.ArrayList;
    3.31 +import java.util.Collections;
    3.32 +import java.util.EventListener;
    3.33 +import java.util.EventListenerProxy;
    3.34 +import java.util.HashMap;
    3.35 +import java.util.List;
    3.36 +import java.util.Map;
    3.37 +import java.util.Map.Entry;
    3.38 +import java.util.Set;
    3.39 +import org.apidesign.bck2brwsr.emul.lang.System;
    3.40 +
    3.41 +/**
    3.42 + * This is an abstract class that provides base functionality
    3.43 + * for the {@link PropertyChangeSupport PropertyChangeSupport} class
    3.44 + * and the {@link VetoableChangeSupport VetoableChangeSupport} class.
    3.45 + *
    3.46 + * @see PropertyChangeListenerMap
    3.47 + * @see VetoableChangeListenerMap
    3.48 + *
    3.49 + * @author Sergey A. Malenkov
    3.50 + */
    3.51 +abstract class ChangeListenerMap<L extends EventListener> {
    3.52 +    private Map<String, L[]> map;
    3.53 +
    3.54 +    /**
    3.55 +     * Creates an array of listeners.
    3.56 +     * This method can be optimized by using
    3.57 +     * the same instance of the empty array
    3.58 +     * when {@code length} is equal to {@code 0}.
    3.59 +     *
    3.60 +     * @param length  the array length
    3.61 +     * @return        an array with specified length
    3.62 +     */
    3.63 +    protected abstract L[] newArray(int length);
    3.64 +
    3.65 +    /**
    3.66 +     * Creates a proxy listener for the specified property.
    3.67 +     *
    3.68 +     * @param name      the name of the property to listen on
    3.69 +     * @param listener  the listener to process events
    3.70 +     * @return          a proxy listener
    3.71 +     */
    3.72 +    protected abstract L newProxy(String name, L listener);
    3.73 +
    3.74 +    /**
    3.75 +     * Adds a listener to the list of listeners for the specified property.
    3.76 +     * This listener is called as many times as it was added.
    3.77 +     *
    3.78 +     * @param name      the name of the property to listen on
    3.79 +     * @param listener  the listener to process events
    3.80 +     */
    3.81 +    public final synchronized void add(String name, L listener) {
    3.82 +        if (this.map == null) {
    3.83 +            this.map = new HashMap<String, L[]>();
    3.84 +        }
    3.85 +        L[] array = this.map.get(name);
    3.86 +        int size = (array != null)
    3.87 +                ? array.length
    3.88 +                : 0;
    3.89 +
    3.90 +        L[] clone = newArray(size + 1);
    3.91 +        clone[size] = listener;
    3.92 +        if (array != null) {
    3.93 +            System.arraycopy(array, 0, clone, 0, size);
    3.94 +        }
    3.95 +        this.map.put(name, clone);
    3.96 +    }
    3.97 +
    3.98 +    /**
    3.99 +     * Removes a listener from the list of listeners for the specified property.
   3.100 +     * If the listener was added more than once to the same event source,
   3.101 +     * this listener will be notified one less time after being removed.
   3.102 +     *
   3.103 +     * @param name      the name of the property to listen on
   3.104 +     * @param listener  the listener to process events
   3.105 +     */
   3.106 +    public final synchronized void remove(String name, L listener) {
   3.107 +        if (this.map != null) {
   3.108 +            L[] array = this.map.get(name);
   3.109 +            if (array != null) {
   3.110 +                for (int i = 0; i < array.length; i++) {
   3.111 +                    if (listener.equals(array[i])) {
   3.112 +                        int size = array.length - 1;
   3.113 +                        if (size > 0) {
   3.114 +                            L[] clone = newArray(size);
   3.115 +                            System.arraycopy(array, 0, clone, 0, i);
   3.116 +                            System.arraycopy(array, i + 1, clone, i, size - i);
   3.117 +                            this.map.put(name, clone);
   3.118 +                        }
   3.119 +                        else {
   3.120 +                            this.map.remove(name);
   3.121 +                            if (this.map.isEmpty()) {
   3.122 +                                this.map = null;
   3.123 +                            }
   3.124 +                        }
   3.125 +                        break;
   3.126 +                    }
   3.127 +                }
   3.128 +            }
   3.129 +        }
   3.130 +    }
   3.131 +
   3.132 +    /**
   3.133 +     * Returns the list of listeners for the specified property.
   3.134 +     *
   3.135 +     * @param name  the name of the property
   3.136 +     * @return      the corresponding list of listeners
   3.137 +     */
   3.138 +    public final synchronized L[] get(String name) {
   3.139 +        return (this.map != null)
   3.140 +                ? this.map.get(name)
   3.141 +                : null;
   3.142 +    }
   3.143 +
   3.144 +    /**
   3.145 +     * Sets new list of listeners for the specified property.
   3.146 +     *
   3.147 +     * @param name       the name of the property
   3.148 +     * @param listeners  new list of listeners
   3.149 +     */
   3.150 +    public final void set(String name, L[] listeners) {
   3.151 +        if (listeners != null) {
   3.152 +            if (this.map == null) {
   3.153 +                this.map = new HashMap<String, L[]>();
   3.154 +            }
   3.155 +            this.map.put(name, listeners);
   3.156 +        }
   3.157 +        else if (this.map != null) {
   3.158 +            this.map.remove(name);
   3.159 +            if (this.map.isEmpty()) {
   3.160 +                this.map = null;
   3.161 +            }
   3.162 +        }
   3.163 +    }
   3.164 +
   3.165 +    /**
   3.166 +     * Returns all listeners in the map.
   3.167 +     *
   3.168 +     * @return an array of all listeners
   3.169 +     */
   3.170 +    public final synchronized L[] getListeners() {
   3.171 +        if (this.map == null) {
   3.172 +            return newArray(0);
   3.173 +        }
   3.174 +        List<L> list = new ArrayList<L>();
   3.175 +
   3.176 +        L[] listeners = this.map.get(null);
   3.177 +        if (listeners != null) {
   3.178 +            for (L listener : listeners) {
   3.179 +                list.add(listener);
   3.180 +            }
   3.181 +        }
   3.182 +        for (Entry<String, L[]> entry : this.map.entrySet()) {
   3.183 +            String name = entry.getKey();
   3.184 +            if (name != null) {
   3.185 +                for (L listener : entry.getValue()) {
   3.186 +                    list.add(newProxy(name, listener));
   3.187 +                }
   3.188 +            }
   3.189 +        }
   3.190 +        return list.toArray(newArray(list.size()));
   3.191 +    }
   3.192 +
   3.193 +    /**
   3.194 +     * Returns listeners that have been associated with the named property.
   3.195 +     *
   3.196 +     * @param name  the name of the property
   3.197 +     * @return an array of listeners for the named property
   3.198 +     */
   3.199 +    public final L[] getListeners(String name) {
   3.200 +        if (name != null) {
   3.201 +            L[] listeners = get(name);
   3.202 +            if (listeners != null) {
   3.203 +                return listeners.clone();
   3.204 +            }
   3.205 +        }
   3.206 +        return newArray(0);
   3.207 +    }
   3.208 +
   3.209 +    /**
   3.210 +     * Indicates whether the map contains
   3.211 +     * at least one listener to be notified.
   3.212 +     *
   3.213 +     * @param name  the name of the property
   3.214 +     * @return      {@code true} if at least one listener exists or
   3.215 +     *              {@code false} otherwise
   3.216 +     */
   3.217 +    public final synchronized boolean hasListeners(String name) {
   3.218 +        if (this.map == null) {
   3.219 +            return false;
   3.220 +        }
   3.221 +        L[] array = this.map.get(null);
   3.222 +        return (array != null) || ((name != null) && (null != this.map.get(name)));
   3.223 +    }
   3.224 +
   3.225 +    /**
   3.226 +     * Returns a set of entries from the map.
   3.227 +     * Each entry is a pair consisted of the property name
   3.228 +     * and the corresponding list of listeners.
   3.229 +     *
   3.230 +     * @return a set of entries from the map
   3.231 +     */
   3.232 +    public final Set<Entry<String, L[]>> getEntries() {
   3.233 +        return (this.map != null)
   3.234 +                ? this.map.entrySet()
   3.235 +                : Collections.<Entry<String, L[]>>emptySet();
   3.236 +    }
   3.237 +
   3.238 +    /**
   3.239 +     * Extracts a real listener from the proxy listener.
   3.240 +     * It is necessary because default proxy class is not serializable.
   3.241 +     *
   3.242 +     * @return a real listener
   3.243 +     */
   3.244 +    public final L extract(L listener) {
   3.245 +        while (listener instanceof EventListenerProxy) {
   3.246 +            EventListenerProxy<L> proxy = (EventListenerProxy<L>) listener;
   3.247 +            listener = proxy.getListener();
   3.248 +        }
   3.249 +        return listener;
   3.250 +    }
   3.251 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/emul/compact/src/main/java/java/beans/IndexedPropertyChangeEvent.java	Tue Feb 05 17:04:22 2013 +0100
     4.3 @@ -0,0 +1,78 @@
     4.4 +/*
     4.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.  Oracle designates this
    4.11 + * particular file as subject to the "Classpath" exception as provided
    4.12 + * by Oracle in the LICENSE file that accompanied this code.
    4.13 + *
    4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 + * version 2 for more details (a copy is included in the LICENSE file that
    4.18 + * accompanied this code).
    4.19 + *
    4.20 + * You should have received a copy of the GNU General Public License version
    4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 + *
    4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.25 + * or visit www.oracle.com if you need additional information or have any
    4.26 + * questions.
    4.27 + */
    4.28 +package java.beans;
    4.29 +
    4.30 +/**
    4.31 + * An "IndexedPropertyChange" event gets delivered whenever a component that
    4.32 + * conforms to the JavaBeans&trade; specification (a "bean") changes a bound
    4.33 + * indexed property. This class is an extension of <code>PropertyChangeEvent</code>
    4.34 + * but contains the index of the property that has changed.
    4.35 + * <P>
    4.36 + * Null values may be provided for the old and the new values if their
    4.37 + * true values are not known.
    4.38 + * <P>
    4.39 + * An event source may send a null object as the name to indicate that an
    4.40 + * arbitrary set of if its properties have changed.  In this case the
    4.41 + * old and new values should also be null.
    4.42 + *
    4.43 + * @since 1.5
    4.44 + * @author Mark Davidson
    4.45 + */
    4.46 +public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
    4.47 +    private static final long serialVersionUID = -320227448495806870L;
    4.48 +
    4.49 +    private int index;
    4.50 +
    4.51 +    /**
    4.52 +     * Constructs a new <code>IndexedPropertyChangeEvent</code> object.
    4.53 +     *
    4.54 +     * @param source  The bean that fired the event.
    4.55 +     * @param propertyName  The programmatic name of the property that
    4.56 +     *             was changed.
    4.57 +     * @param oldValue      The old value of the property.
    4.58 +     * @param newValue      The new value of the property.
    4.59 +     * @param index index of the property element that was changed.
    4.60 +     */
    4.61 +    public IndexedPropertyChangeEvent(Object source, String propertyName,
    4.62 +                                      Object oldValue, Object newValue,
    4.63 +                                      int index) {
    4.64 +        super (source, propertyName, oldValue, newValue);
    4.65 +        this.index = index;
    4.66 +    }
    4.67 +
    4.68 +    /**
    4.69 +     * Gets the index of the property that was changed.
    4.70 +     *
    4.71 +     * @return The index specifying the property element that was
    4.72 +     *         changed.
    4.73 +     */
    4.74 +    public int getIndex() {
    4.75 +        return index;
    4.76 +    }
    4.77 +
    4.78 +    void appendTo(StringBuilder sb) {
    4.79 +        sb.append("; index=").append(getIndex());
    4.80 +    }
    4.81 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeEvent.java	Tue Feb 05 17:04:22 2013 +0100
     5.3 @@ -0,0 +1,164 @@
     5.4 +/*
     5.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.  Oracle designates this
    5.11 + * particular file as subject to the "Classpath" exception as provided
    5.12 + * by Oracle in the LICENSE file that accompanied this code.
    5.13 + *
    5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.17 + * version 2 for more details (a copy is included in the LICENSE file that
    5.18 + * accompanied this code).
    5.19 + *
    5.20 + * You should have received a copy of the GNU General Public License version
    5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.23 + *
    5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.25 + * or visit www.oracle.com if you need additional information or have any
    5.26 + * questions.
    5.27 + */
    5.28 +
    5.29 +package java.beans;
    5.30 +
    5.31 +/**
    5.32 + * A "PropertyChange" event gets delivered whenever a bean changes a "bound"
    5.33 + * or "constrained" property.  A PropertyChangeEvent object is sent as an
    5.34 + * argument to the PropertyChangeListener and VetoableChangeListener methods.
    5.35 + * <P>
    5.36 + * Normally PropertyChangeEvents are accompanied by the name and the old
    5.37 + * and new value of the changed property.  If the new value is a primitive
    5.38 + * type (such as int or boolean) it must be wrapped as the
    5.39 + * corresponding java.lang.* Object type (such as Integer or Boolean).
    5.40 + * <P>
    5.41 + * Null values may be provided for the old and the new values if their
    5.42 + * true values are not known.
    5.43 + * <P>
    5.44 + * An event source may send a null object as the name to indicate that an
    5.45 + * arbitrary set of if its properties have changed.  In this case the
    5.46 + * old and new values should also be null.
    5.47 + */
    5.48 +
    5.49 +public class PropertyChangeEvent extends java.util.EventObject {
    5.50 +    private static final long serialVersionUID = 7042693688939648123L;
    5.51 +
    5.52 +    /**
    5.53 +     * Constructs a new <code>PropertyChangeEvent</code>.
    5.54 +     *
    5.55 +     * @param source  The bean that fired the event.
    5.56 +     * @param propertyName  The programmatic name of the property
    5.57 +     *          that was changed.
    5.58 +     * @param oldValue  The old value of the property.
    5.59 +     * @param newValue  The new value of the property.
    5.60 +     */
    5.61 +    public PropertyChangeEvent(Object source, String propertyName,
    5.62 +                                     Object oldValue, Object newValue) {
    5.63 +        super(source);
    5.64 +        this.propertyName = propertyName;
    5.65 +        this.newValue = newValue;
    5.66 +        this.oldValue = oldValue;
    5.67 +    }
    5.68 +
    5.69 +    /**
    5.70 +     * Gets the programmatic name of the property that was changed.
    5.71 +     *
    5.72 +     * @return  The programmatic name of the property that was changed.
    5.73 +     *          May be null if multiple properties have changed.
    5.74 +     */
    5.75 +    public String getPropertyName() {
    5.76 +        return propertyName;
    5.77 +    }
    5.78 +
    5.79 +    /**
    5.80 +     * Gets the new value for the property, expressed as an Object.
    5.81 +     *
    5.82 +     * @return  The new value for the property, expressed as an Object.
    5.83 +     *          May be null if multiple properties have changed.
    5.84 +     */
    5.85 +    public Object getNewValue() {
    5.86 +        return newValue;
    5.87 +    }
    5.88 +
    5.89 +    /**
    5.90 +     * Gets the old value for the property, expressed as an Object.
    5.91 +     *
    5.92 +     * @return  The old value for the property, expressed as an Object.
    5.93 +     *          May be null if multiple properties have changed.
    5.94 +     */
    5.95 +    public Object getOldValue() {
    5.96 +        return oldValue;
    5.97 +    }
    5.98 +
    5.99 +    /**
   5.100 +     * Sets the propagationId object for the event.
   5.101 +     *
   5.102 +     * @param propagationId  The propagationId object for the event.
   5.103 +     */
   5.104 +    public void setPropagationId(Object propagationId) {
   5.105 +        this.propagationId = propagationId;
   5.106 +    }
   5.107 +
   5.108 +    /**
   5.109 +     * The "propagationId" field is reserved for future use.  In Beans 1.0
   5.110 +     * the sole requirement is that if a listener catches a PropertyChangeEvent
   5.111 +     * and then fires a PropertyChangeEvent of its own, then it should
   5.112 +     * make sure that it propagates the propagationId field from its
   5.113 +     * incoming event to its outgoing event.
   5.114 +     *
   5.115 +     * @return the propagationId object associated with a bound/constrained
   5.116 +     *          property update.
   5.117 +     */
   5.118 +    public Object getPropagationId() {
   5.119 +        return propagationId;
   5.120 +    }
   5.121 +
   5.122 +    /**
   5.123 +     * name of the property that changed.  May be null, if not known.
   5.124 +     * @serial
   5.125 +     */
   5.126 +    private String propertyName;
   5.127 +
   5.128 +    /**
   5.129 +     * New value for property.  May be null if not known.
   5.130 +     * @serial
   5.131 +     */
   5.132 +    private Object newValue;
   5.133 +
   5.134 +    /**
   5.135 +     * Previous value for property.  May be null if not known.
   5.136 +     * @serial
   5.137 +     */
   5.138 +    private Object oldValue;
   5.139 +
   5.140 +    /**
   5.141 +     * Propagation ID.  May be null.
   5.142 +     * @serial
   5.143 +     * @see #getPropagationId
   5.144 +     */
   5.145 +    private Object propagationId;
   5.146 +
   5.147 +    /**
   5.148 +     * Returns a string representation of the object.
   5.149 +     *
   5.150 +     * @return a string representation of the object
   5.151 +     *
   5.152 +     * @since 1.7
   5.153 +     */
   5.154 +    public String toString() {
   5.155 +        StringBuilder sb = new StringBuilder(getClass().getName());
   5.156 +        sb.append("[propertyName=").append(getPropertyName());
   5.157 +        appendTo(sb);
   5.158 +        sb.append("; oldValue=").append(getOldValue());
   5.159 +        sb.append("; newValue=").append(getNewValue());
   5.160 +        sb.append("; propagationId=").append(getPropagationId());
   5.161 +        sb.append("; source=").append(getSource());
   5.162 +        return sb.append("]").toString();
   5.163 +    }
   5.164 +
   5.165 +    void appendTo(StringBuilder sb) {
   5.166 +    }
   5.167 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeListener.java	Tue Feb 05 17:04:22 2013 +0100
     6.3 @@ -0,0 +1,44 @@
     6.4 +/*
     6.5 + * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.  Oracle designates this
    6.11 + * particular file as subject to the "Classpath" exception as provided
    6.12 + * by Oracle in the LICENSE file that accompanied this code.
    6.13 + *
    6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.17 + * version 2 for more details (a copy is included in the LICENSE file that
    6.18 + * accompanied this code).
    6.19 + *
    6.20 + * You should have received a copy of the GNU General Public License version
    6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.23 + *
    6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.25 + * or visit www.oracle.com if you need additional information or have any
    6.26 + * questions.
    6.27 + */
    6.28 +
    6.29 +package java.beans;
    6.30 +
    6.31 +/**
    6.32 + * A "PropertyChange" event gets fired whenever a bean changes a "bound"
    6.33 + * property.  You can register a PropertyChangeListener with a source
    6.34 + * bean so as to be notified of any bound property updates.
    6.35 + */
    6.36 +
    6.37 +public interface PropertyChangeListener extends java.util.EventListener {
    6.38 +
    6.39 +    /**
    6.40 +     * This method gets called when a bound property is changed.
    6.41 +     * @param evt A PropertyChangeEvent object describing the event source
    6.42 +     *          and the property that has changed.
    6.43 +     */
    6.44 +
    6.45 +    void propertyChange(PropertyChangeEvent evt);
    6.46 +
    6.47 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeListenerProxy.java	Tue Feb 05 17:04:22 2013 +0100
     7.3 @@ -0,0 +1,81 @@
     7.4 +/*
     7.5 + * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.  Oracle designates this
    7.11 + * particular file as subject to the "Classpath" exception as provided
    7.12 + * by Oracle in the LICENSE file that accompanied this code.
    7.13 + *
    7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 + * version 2 for more details (a copy is included in the LICENSE file that
    7.18 + * accompanied this code).
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License version
    7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 + *
    7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.25 + * or visit www.oracle.com if you need additional information or have any
    7.26 + * questions.
    7.27 + */
    7.28 +
    7.29 +package java.beans;
    7.30 +
    7.31 +import java.util.EventListenerProxy;
    7.32 +
    7.33 +/**
    7.34 + * A class which extends the {@code EventListenerProxy}
    7.35 + * specifically for adding a {@code PropertyChangeListener}
    7.36 + * with a "bound" property.
    7.37 + * Instances of this class can be added
    7.38 + * as {@code PropertyChangeListener}s to a bean
    7.39 + * which supports firing property change events.
    7.40 + * <p>
    7.41 + * If the object has a {@code getPropertyChangeListeners} method
    7.42 + * then the array returned could be a mixture of {@code PropertyChangeListener}
    7.43 + * and {@code PropertyChangeListenerProxy} objects.
    7.44 + *
    7.45 + * @see java.util.EventListenerProxy
    7.46 + * @see PropertyChangeSupport#getPropertyChangeListeners
    7.47 + * @since 1.4
    7.48 + */
    7.49 +public class PropertyChangeListenerProxy
    7.50 +        extends EventListenerProxy<PropertyChangeListener>
    7.51 +        implements PropertyChangeListener {
    7.52 +
    7.53 +    private final String propertyName;
    7.54 +
    7.55 +    /**
    7.56 +     * Constructor which binds the {@code PropertyChangeListener}
    7.57 +     * to a specific property.
    7.58 +     *
    7.59 +     * @param propertyName  the name of the property to listen on
    7.60 +     * @param listener      the listener object
    7.61 +     */
    7.62 +    public PropertyChangeListenerProxy(String propertyName, PropertyChangeListener listener) {
    7.63 +        super(listener);
    7.64 +        this.propertyName = propertyName;
    7.65 +    }
    7.66 +
    7.67 +    /**
    7.68 +     * Forwards the property change event to the listener delegate.
    7.69 +     *
    7.70 +     * @param event  the property change event
    7.71 +     */
    7.72 +    public void propertyChange(PropertyChangeEvent event) {
    7.73 +        getListener().propertyChange(event);
    7.74 +    }
    7.75 +
    7.76 +    /**
    7.77 +     * Returns the name of the named property associated with the listener.
    7.78 +     *
    7.79 +     * @return the name of the named property associated with the listener
    7.80 +     */
    7.81 +    public String getPropertyName() {
    7.82 +        return this.propertyName;
    7.83 +    }
    7.84 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeSupport.java	Tue Feb 05 17:04:22 2013 +0100
     8.3 @@ -0,0 +1,536 @@
     8.4 +/*
     8.5 + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.  Oracle designates this
    8.11 + * particular file as subject to the "Classpath" exception as provided
    8.12 + * by Oracle in the LICENSE file that accompanied this code.
    8.13 + *
    8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.17 + * version 2 for more details (a copy is included in the LICENSE file that
    8.18 + * accompanied this code).
    8.19 + *
    8.20 + * You should have received a copy of the GNU General Public License version
    8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.23 + *
    8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.25 + * or visit www.oracle.com if you need additional information or have any
    8.26 + * questions.
    8.27 + */
    8.28 +package java.beans;
    8.29 +
    8.30 +import java.io.Serializable;
    8.31 +import java.io.ObjectStreamField;
    8.32 +import java.io.ObjectOutputStream;
    8.33 +import java.io.ObjectInputStream;
    8.34 +import java.io.IOException;
    8.35 +import java.util.Hashtable;
    8.36 +import java.util.Map.Entry;
    8.37 +
    8.38 +/**
    8.39 + * This is a utility class that can be used by beans that support bound
    8.40 + * properties.  It manages a list of listeners and dispatches
    8.41 + * {@link PropertyChangeEvent}s to them.  You can use an instance of this class
    8.42 + * as a member field of your bean and delegate these types of work to it.
    8.43 + * The {@link PropertyChangeListener} can be registered for all properties
    8.44 + * or for a property specified by name.
    8.45 + * <p>
    8.46 + * Here is an example of {@code PropertyChangeSupport} usage that follows
    8.47 + * the rules and recommendations laid out in the JavaBeans&trade; specification:
    8.48 + * <pre>
    8.49 + * public class MyBean {
    8.50 + *     private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    8.51 + *
    8.52 + *     public void addPropertyChangeListener(PropertyChangeListener listener) {
    8.53 + *         this.pcs.addPropertyChangeListener(listener);
    8.54 + *     }
    8.55 + *
    8.56 + *     public void removePropertyChangeListener(PropertyChangeListener listener) {
    8.57 + *         this.pcs.removePropertyChangeListener(listener);
    8.58 + *     }
    8.59 + *
    8.60 + *     private String value;
    8.61 + *
    8.62 + *     public String getValue() {
    8.63 + *         return this.value;
    8.64 + *     }
    8.65 + *
    8.66 + *     public void setValue(String newValue) {
    8.67 + *         String oldValue = this.value;
    8.68 + *         this.value = newValue;
    8.69 + *         this.pcs.firePropertyChange("value", oldValue, newValue);
    8.70 + *     }
    8.71 + *
    8.72 + *     [...]
    8.73 + * }
    8.74 + * </pre>
    8.75 + * <p>
    8.76 + * A {@code PropertyChangeSupport} instance is thread-safe.
    8.77 + * <p>
    8.78 + * This class is serializable.  When it is serialized it will save
    8.79 + * (and restore) any listeners that are themselves serializable.  Any
    8.80 + * non-serializable listeners will be skipped during serialization.
    8.81 + *
    8.82 + * @see VetoableChangeSupport
    8.83 + */
    8.84 +public class PropertyChangeSupport implements Serializable {
    8.85 +    private PropertyChangeListenerMap map = new PropertyChangeListenerMap();
    8.86 +
    8.87 +    /**
    8.88 +     * Constructs a <code>PropertyChangeSupport</code> object.
    8.89 +     *
    8.90 +     * @param sourceBean  The bean to be given as the source for any events.
    8.91 +     */
    8.92 +    public PropertyChangeSupport(Object sourceBean) {
    8.93 +        if (sourceBean == null) {
    8.94 +            throw new NullPointerException();
    8.95 +        }
    8.96 +        source = sourceBean;
    8.97 +    }
    8.98 +
    8.99 +    /**
   8.100 +     * Add a PropertyChangeListener to the listener list.
   8.101 +     * The listener is registered for all properties.
   8.102 +     * The same listener object may be added more than once, and will be called
   8.103 +     * as many times as it is added.
   8.104 +     * If <code>listener</code> is null, no exception is thrown and no action
   8.105 +     * is taken.
   8.106 +     *
   8.107 +     * @param listener  The PropertyChangeListener to be added
   8.108 +     */
   8.109 +    public void addPropertyChangeListener(PropertyChangeListener listener) {
   8.110 +        if (listener == null) {
   8.111 +            return;
   8.112 +        }
   8.113 +        if (listener instanceof PropertyChangeListenerProxy) {
   8.114 +            PropertyChangeListenerProxy proxy =
   8.115 +                   (PropertyChangeListenerProxy)listener;
   8.116 +            // Call two argument add method.
   8.117 +            addPropertyChangeListener(proxy.getPropertyName(),
   8.118 +                                      proxy.getListener());
   8.119 +        } else {
   8.120 +            this.map.add(null, listener);
   8.121 +        }
   8.122 +    }
   8.123 +
   8.124 +    /**
   8.125 +     * Remove a PropertyChangeListener from the listener list.
   8.126 +     * This removes a PropertyChangeListener that was registered
   8.127 +     * for all properties.
   8.128 +     * If <code>listener</code> was added more than once to the same event
   8.129 +     * source, it will be notified one less time after being removed.
   8.130 +     * If <code>listener</code> is null, or was never added, no exception is
   8.131 +     * thrown and no action is taken.
   8.132 +     *
   8.133 +     * @param listener  The PropertyChangeListener to be removed
   8.134 +     */
   8.135 +    public void removePropertyChangeListener(PropertyChangeListener listener) {
   8.136 +        if (listener == null) {
   8.137 +            return;
   8.138 +        }
   8.139 +        if (listener instanceof PropertyChangeListenerProxy) {
   8.140 +            PropertyChangeListenerProxy proxy =
   8.141 +                    (PropertyChangeListenerProxy)listener;
   8.142 +            // Call two argument remove method.
   8.143 +            removePropertyChangeListener(proxy.getPropertyName(),
   8.144 +                                         proxy.getListener());
   8.145 +        } else {
   8.146 +            this.map.remove(null, listener);
   8.147 +        }
   8.148 +    }
   8.149 +
   8.150 +    /**
   8.151 +     * Returns an array of all the listeners that were added to the
   8.152 +     * PropertyChangeSupport object with addPropertyChangeListener().
   8.153 +     * <p>
   8.154 +     * If some listeners have been added with a named property, then
   8.155 +     * the returned array will be a mixture of PropertyChangeListeners
   8.156 +     * and <code>PropertyChangeListenerProxy</code>s. If the calling
   8.157 +     * method is interested in distinguishing the listeners then it must
   8.158 +     * test each element to see if it's a
   8.159 +     * <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
   8.160 +     * the parameter.
   8.161 +     *
   8.162 +     * <pre>
   8.163 +     * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
   8.164 +     * for (int i = 0; i < listeners.length; i++) {
   8.165 +     *   if (listeners[i] instanceof PropertyChangeListenerProxy) {
   8.166 +     *     PropertyChangeListenerProxy proxy =
   8.167 +     *                    (PropertyChangeListenerProxy)listeners[i];
   8.168 +     *     if (proxy.getPropertyName().equals("foo")) {
   8.169 +     *       // proxy is a PropertyChangeListener which was associated
   8.170 +     *       // with the property named "foo"
   8.171 +     *     }
   8.172 +     *   }
   8.173 +     * }
   8.174 +     *</pre>
   8.175 +     *
   8.176 +     * @see PropertyChangeListenerProxy
   8.177 +     * @return all of the <code>PropertyChangeListeners</code> added or an
   8.178 +     *         empty array if no listeners have been added
   8.179 +     * @since 1.4
   8.180 +     */
   8.181 +    public PropertyChangeListener[] getPropertyChangeListeners() {
   8.182 +        return this.map.getListeners();
   8.183 +    }
   8.184 +
   8.185 +    /**
   8.186 +     * Add a PropertyChangeListener for a specific property.  The listener
   8.187 +     * will be invoked only when a call on firePropertyChange names that
   8.188 +     * specific property.
   8.189 +     * The same listener object may be added more than once.  For each
   8.190 +     * property,  the listener will be invoked the number of times it was added
   8.191 +     * for that property.
   8.192 +     * If <code>propertyName</code> or <code>listener</code> is null, no
   8.193 +     * exception is thrown and no action is taken.
   8.194 +     *
   8.195 +     * @param propertyName  The name of the property to listen on.
   8.196 +     * @param listener  The PropertyChangeListener to be added
   8.197 +     */
   8.198 +    public void addPropertyChangeListener(
   8.199 +                String propertyName,
   8.200 +                PropertyChangeListener listener) {
   8.201 +        if (listener == null || propertyName == null) {
   8.202 +            return;
   8.203 +        }
   8.204 +        listener = this.map.extract(listener);
   8.205 +        if (listener != null) {
   8.206 +            this.map.add(propertyName, listener);
   8.207 +        }
   8.208 +    }
   8.209 +
   8.210 +    /**
   8.211 +     * Remove a PropertyChangeListener for a specific property.
   8.212 +     * If <code>listener</code> was added more than once to the same event
   8.213 +     * source for the specified property, it will be notified one less time
   8.214 +     * after being removed.
   8.215 +     * If <code>propertyName</code> is null,  no exception is thrown and no
   8.216 +     * action is taken.
   8.217 +     * If <code>listener</code> is null, or was never added for the specified
   8.218 +     * property, no exception is thrown and no action is taken.
   8.219 +     *
   8.220 +     * @param propertyName  The name of the property that was listened on.
   8.221 +     * @param listener  The PropertyChangeListener to be removed
   8.222 +     */
   8.223 +    public void removePropertyChangeListener(
   8.224 +                String propertyName,
   8.225 +                PropertyChangeListener listener) {
   8.226 +        if (listener == null || propertyName == null) {
   8.227 +            return;
   8.228 +        }
   8.229 +        listener = this.map.extract(listener);
   8.230 +        if (listener != null) {
   8.231 +            this.map.remove(propertyName, listener);
   8.232 +        }
   8.233 +    }
   8.234 +
   8.235 +    /**
   8.236 +     * Returns an array of all the listeners which have been associated
   8.237 +     * with the named property.
   8.238 +     *
   8.239 +     * @param propertyName  The name of the property being listened to
   8.240 +     * @return all of the <code>PropertyChangeListeners</code> associated with
   8.241 +     *         the named property.  If no such listeners have been added,
   8.242 +     *         or if <code>propertyName</code> is null, an empty array is
   8.243 +     *         returned.
   8.244 +     * @since 1.4
   8.245 +     */
   8.246 +    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
   8.247 +        return this.map.getListeners(propertyName);
   8.248 +    }
   8.249 +
   8.250 +    /**
   8.251 +     * Reports a bound property update to listeners
   8.252 +     * that have been registered to track updates of
   8.253 +     * all properties or a property with the specified name.
   8.254 +     * <p>
   8.255 +     * No event is fired if old and new values are equal and non-null.
   8.256 +     * <p>
   8.257 +     * This is merely a convenience wrapper around the more general
   8.258 +     * {@link #firePropertyChange(PropertyChangeEvent)} method.
   8.259 +     *
   8.260 +     * @param propertyName  the programmatic name of the property that was changed
   8.261 +     * @param oldValue      the old value of the property
   8.262 +     * @param newValue      the new value of the property
   8.263 +     */
   8.264 +    public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
   8.265 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
   8.266 +            firePropertyChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
   8.267 +        }
   8.268 +    }
   8.269 +
   8.270 +    /**
   8.271 +     * Reports an integer bound property update to listeners
   8.272 +     * that have been registered to track updates of
   8.273 +     * all properties or a property with the specified name.
   8.274 +     * <p>
   8.275 +     * No event is fired if old and new values are equal.
   8.276 +     * <p>
   8.277 +     * This is merely a convenience wrapper around the more general
   8.278 +     * {@link #firePropertyChange(String, Object, Object)}  method.
   8.279 +     *
   8.280 +     * @param propertyName  the programmatic name of the property that was changed
   8.281 +     * @param oldValue      the old value of the property
   8.282 +     * @param newValue      the new value of the property
   8.283 +     */
   8.284 +    public void firePropertyChange(String propertyName, int oldValue, int newValue) {
   8.285 +        if (oldValue != newValue) {
   8.286 +            firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
   8.287 +        }
   8.288 +    }
   8.289 +
   8.290 +    /**
   8.291 +     * Reports a boolean bound property update to listeners
   8.292 +     * that have been registered to track updates of
   8.293 +     * all properties or a property with the specified name.
   8.294 +     * <p>
   8.295 +     * No event is fired if old and new values are equal.
   8.296 +     * <p>
   8.297 +     * This is merely a convenience wrapper around the more general
   8.298 +     * {@link #firePropertyChange(String, Object, Object)}  method.
   8.299 +     *
   8.300 +     * @param propertyName  the programmatic name of the property that was changed
   8.301 +     * @param oldValue      the old value of the property
   8.302 +     * @param newValue      the new value of the property
   8.303 +     */
   8.304 +    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
   8.305 +        if (oldValue != newValue) {
   8.306 +            firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
   8.307 +        }
   8.308 +    }
   8.309 +
   8.310 +    /**
   8.311 +     * Fires a property change event to listeners
   8.312 +     * that have been registered to track updates of
   8.313 +     * all properties or a property with the specified name.
   8.314 +     * <p>
   8.315 +     * No event is fired if the given event's old and new values are equal and non-null.
   8.316 +     *
   8.317 +     * @param event  the {@code PropertyChangeEvent} to be fired
   8.318 +     */
   8.319 +    public void firePropertyChange(PropertyChangeEvent event) {
   8.320 +        Object oldValue = event.getOldValue();
   8.321 +        Object newValue = event.getNewValue();
   8.322 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
   8.323 +            String name = event.getPropertyName();
   8.324 +
   8.325 +            PropertyChangeListener[] common = this.map.get(null);
   8.326 +            PropertyChangeListener[] named = (name != null)
   8.327 +                        ? this.map.get(name)
   8.328 +                        : null;
   8.329 +
   8.330 +            fire(common, event);
   8.331 +            fire(named, event);
   8.332 +        }
   8.333 +    }
   8.334 +
   8.335 +    private static void fire(PropertyChangeListener[] listeners, PropertyChangeEvent event) {
   8.336 +        if (listeners != null) {
   8.337 +            for (PropertyChangeListener listener : listeners) {
   8.338 +                listener.propertyChange(event);
   8.339 +            }
   8.340 +        }
   8.341 +    }
   8.342 +
   8.343 +    /**
   8.344 +     * Reports a bound indexed property update to listeners
   8.345 +     * that have been registered to track updates of
   8.346 +     * all properties or a property with the specified name.
   8.347 +     * <p>
   8.348 +     * No event is fired if old and new values are equal and non-null.
   8.349 +     * <p>
   8.350 +     * This is merely a convenience wrapper around the more general
   8.351 +     * {@link #firePropertyChange(PropertyChangeEvent)} method.
   8.352 +     *
   8.353 +     * @param propertyName  the programmatic name of the property that was changed
   8.354 +     * @param index         the index of the property element that was changed
   8.355 +     * @param oldValue      the old value of the property
   8.356 +     * @param newValue      the new value of the property
   8.357 +     * @since 1.5
   8.358 +     */
   8.359 +    public void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
   8.360 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
   8.361 +            firePropertyChange(new IndexedPropertyChangeEvent(source, propertyName, oldValue, newValue, index));
   8.362 +        }
   8.363 +    }
   8.364 +
   8.365 +    /**
   8.366 +     * Reports an integer bound indexed property update to listeners
   8.367 +     * that have been registered to track updates of
   8.368 +     * all properties or a property with the specified name.
   8.369 +     * <p>
   8.370 +     * No event is fired if old and new values are equal.
   8.371 +     * <p>
   8.372 +     * This is merely a convenience wrapper around the more general
   8.373 +     * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
   8.374 +     *
   8.375 +     * @param propertyName  the programmatic name of the property that was changed
   8.376 +     * @param index         the index of the property element that was changed
   8.377 +     * @param oldValue      the old value of the property
   8.378 +     * @param newValue      the new value of the property
   8.379 +     * @since 1.5
   8.380 +     */
   8.381 +    public void fireIndexedPropertyChange(String propertyName, int index, int oldValue, int newValue) {
   8.382 +        if (oldValue != newValue) {
   8.383 +            fireIndexedPropertyChange(propertyName, index, Integer.valueOf(oldValue), Integer.valueOf(newValue));
   8.384 +        }
   8.385 +    }
   8.386 +
   8.387 +    /**
   8.388 +     * Reports a boolean bound indexed property update to listeners
   8.389 +     * that have been registered to track updates of
   8.390 +     * all properties or a property with the specified name.
   8.391 +     * <p>
   8.392 +     * No event is fired if old and new values are equal.
   8.393 +     * <p>
   8.394 +     * This is merely a convenience wrapper around the more general
   8.395 +     * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
   8.396 +     *
   8.397 +     * @param propertyName  the programmatic name of the property that was changed
   8.398 +     * @param index         the index of the property element that was changed
   8.399 +     * @param oldValue      the old value of the property
   8.400 +     * @param newValue      the new value of the property
   8.401 +     * @since 1.5
   8.402 +     */
   8.403 +    public void fireIndexedPropertyChange(String propertyName, int index, boolean oldValue, boolean newValue) {
   8.404 +        if (oldValue != newValue) {
   8.405 +            fireIndexedPropertyChange(propertyName, index, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
   8.406 +        }
   8.407 +    }
   8.408 +
   8.409 +    /**
   8.410 +     * Check if there are any listeners for a specific property, including
   8.411 +     * those registered on all properties.  If <code>propertyName</code>
   8.412 +     * is null, only check for listeners registered on all properties.
   8.413 +     *
   8.414 +     * @param propertyName  the property name.
   8.415 +     * @return true if there are one or more listeners for the given property
   8.416 +     */
   8.417 +    public boolean hasListeners(String propertyName) {
   8.418 +        return this.map.hasListeners(propertyName);
   8.419 +    }
   8.420 +
   8.421 +    /**
   8.422 +     * @serialData Null terminated list of <code>PropertyChangeListeners</code>.
   8.423 +     * <p>
   8.424 +     * At serialization time we skip non-serializable listeners and
   8.425 +     * only serialize the serializable listeners.
   8.426 +     */
   8.427 +    private void writeObject(ObjectOutputStream s) throws IOException {
   8.428 +        Hashtable<String, PropertyChangeSupport> children = null;
   8.429 +        PropertyChangeListener[] listeners = null;
   8.430 +        synchronized (this.map) {
   8.431 +            for (Entry<String, PropertyChangeListener[]> entry : this.map.getEntries()) {
   8.432 +                String property = entry.getKey();
   8.433 +                if (property == null) {
   8.434 +                    listeners = entry.getValue();
   8.435 +                } else {
   8.436 +                    if (children == null) {
   8.437 +                        children = new Hashtable<String, PropertyChangeSupport>();
   8.438 +                    }
   8.439 +                    PropertyChangeSupport pcs = new PropertyChangeSupport(this.source);
   8.440 +                    pcs.map.set(null, entry.getValue());
   8.441 +                    children.put(property, pcs);
   8.442 +                }
   8.443 +            }
   8.444 +        }
   8.445 +        ObjectOutputStream.PutField fields = s.putFields();
   8.446 +        fields.put("children", children);
   8.447 +        fields.put("source", this.source);
   8.448 +        fields.put("propertyChangeSupportSerializedDataVersion", 2);
   8.449 +        s.writeFields();
   8.450 +
   8.451 +        if (listeners != null) {
   8.452 +            for (PropertyChangeListener l : listeners) {
   8.453 +                if (l instanceof Serializable) {
   8.454 +                    s.writeObject(l);
   8.455 +                }
   8.456 +            }
   8.457 +        }
   8.458 +        s.writeObject(null);
   8.459 +    }
   8.460 +
   8.461 +    private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
   8.462 +        this.map = new PropertyChangeListenerMap();
   8.463 +
   8.464 +        ObjectInputStream.GetField fields = s.readFields();
   8.465 +
   8.466 +        Hashtable<String, PropertyChangeSupport> children = (Hashtable<String, PropertyChangeSupport>) fields.get("children", null);
   8.467 +        this.source = fields.get("source", null);
   8.468 +        fields.get("propertyChangeSupportSerializedDataVersion", 2);
   8.469 +
   8.470 +        Object listenerOrNull;
   8.471 +        while (null != (listenerOrNull = s.readObject())) {
   8.472 +            this.map.add(null, (PropertyChangeListener)listenerOrNull);
   8.473 +        }
   8.474 +        if (children != null) {
   8.475 +            for (Entry<String, PropertyChangeSupport> entry : children.entrySet()) {
   8.476 +                for (PropertyChangeListener listener : entry.getValue().getPropertyChangeListeners()) {
   8.477 +                    this.map.add(entry.getKey(), listener);
   8.478 +                }
   8.479 +            }
   8.480 +        }
   8.481 +    }
   8.482 +
   8.483 +    /**
   8.484 +     * The object to be provided as the "source" for any generated events.
   8.485 +     */
   8.486 +    private Object source;
   8.487 +
   8.488 +    /**
   8.489 +     * @serialField children                                   Hashtable
   8.490 +     * @serialField source                                     Object
   8.491 +     * @serialField propertyChangeSupportSerializedDataVersion int
   8.492 +     */
   8.493 +    private static final ObjectStreamField[] serialPersistentFields = {
   8.494 +            new ObjectStreamField("children", Hashtable.class),
   8.495 +            new ObjectStreamField("source", Object.class),
   8.496 +            new ObjectStreamField("propertyChangeSupportSerializedDataVersion", Integer.TYPE)
   8.497 +    };
   8.498 +
   8.499 +    /**
   8.500 +     * Serialization version ID, so we're compatible with JDK 1.1
   8.501 +     */
   8.502 +    static final long serialVersionUID = 6401253773779951803L;
   8.503 +
   8.504 +    /**
   8.505 +     * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
   8.506 +     * that works with {@link PropertyChangeListener PropertyChangeListener} objects.
   8.507 +     */
   8.508 +    private static final class PropertyChangeListenerMap extends ChangeListenerMap<PropertyChangeListener> {
   8.509 +        private static final PropertyChangeListener[] EMPTY = {};
   8.510 +
   8.511 +        /**
   8.512 +         * Creates an array of {@link PropertyChangeListener PropertyChangeListener} objects.
   8.513 +         * This method uses the same instance of the empty array
   8.514 +         * when {@code length} equals {@code 0}.
   8.515 +         *
   8.516 +         * @param length  the array length
   8.517 +         * @return        an array with specified length
   8.518 +         */
   8.519 +        @Override
   8.520 +        protected PropertyChangeListener[] newArray(int length) {
   8.521 +            return (0 < length)
   8.522 +                    ? new PropertyChangeListener[length]
   8.523 +                    : EMPTY;
   8.524 +        }
   8.525 +
   8.526 +        /**
   8.527 +         * Creates a {@link PropertyChangeListenerProxy PropertyChangeListenerProxy}
   8.528 +         * object for the specified property.
   8.529 +         *
   8.530 +         * @param name      the name of the property to listen on
   8.531 +         * @param listener  the listener to process events
   8.532 +         * @return          a {@code PropertyChangeListenerProxy} object
   8.533 +         */
   8.534 +        @Override
   8.535 +        protected PropertyChangeListener newProxy(String name, PropertyChangeListener listener) {
   8.536 +            return new PropertyChangeListenerProxy(name, listener);
   8.537 +        }
   8.538 +    }
   8.539 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/emul/compact/src/main/java/java/beans/PropertyVetoException.java	Tue Feb 05 17:04:22 2013 +0100
     9.3 @@ -0,0 +1,64 @@
     9.4 +/*
     9.5 + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.  Oracle designates this
    9.11 + * particular file as subject to the "Classpath" exception as provided
    9.12 + * by Oracle in the LICENSE file that accompanied this code.
    9.13 + *
    9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.17 + * version 2 for more details (a copy is included in the LICENSE file that
    9.18 + * accompanied this code).
    9.19 + *
    9.20 + * You should have received a copy of the GNU General Public License version
    9.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.23 + *
    9.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.25 + * or visit www.oracle.com if you need additional information or have any
    9.26 + * questions.
    9.27 + */
    9.28 +
    9.29 +package java.beans;
    9.30 +
    9.31 +
    9.32 +/**
    9.33 + * A PropertyVetoException is thrown when a proposed change to a
    9.34 + * property represents an unacceptable value.
    9.35 + */
    9.36 +
    9.37 +public
    9.38 +class PropertyVetoException extends Exception {
    9.39 +    private static final long serialVersionUID = 129596057694162164L;
    9.40 +
    9.41 +    /**
    9.42 +     * Constructs a <code>PropertyVetoException</code> with a
    9.43 +     * detailed message.
    9.44 +     *
    9.45 +     * @param mess Descriptive message
    9.46 +     * @param evt A PropertyChangeEvent describing the vetoed change.
    9.47 +     */
    9.48 +    public PropertyVetoException(String mess, PropertyChangeEvent evt) {
    9.49 +        super(mess);
    9.50 +        this.evt = evt;
    9.51 +    }
    9.52 +
    9.53 +     /**
    9.54 +     * Gets the vetoed <code>PropertyChangeEvent</code>.
    9.55 +     *
    9.56 +     * @return A PropertyChangeEvent describing the vetoed change.
    9.57 +     */
    9.58 +    public PropertyChangeEvent getPropertyChangeEvent() {
    9.59 +        return evt;
    9.60 +    }
    9.61 +
    9.62 +    /**
    9.63 +     * A PropertyChangeEvent describing the vetoed change.
    9.64 +     * @serial
    9.65 +     */
    9.66 +    private PropertyChangeEvent evt;
    9.67 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeListener.java	Tue Feb 05 17:04:22 2013 +0100
    10.3 @@ -0,0 +1,44 @@
    10.4 +/*
    10.5 + * Copyright (c) 1996, 1997, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.  Oracle designates this
   10.11 + * particular file as subject to the "Classpath" exception as provided
   10.12 + * by Oracle in the LICENSE file that accompanied this code.
   10.13 + *
   10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.17 + * version 2 for more details (a copy is included in the LICENSE file that
   10.18 + * accompanied this code).
   10.19 + *
   10.20 + * You should have received a copy of the GNU General Public License version
   10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.23 + *
   10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.25 + * or visit www.oracle.com if you need additional information or have any
   10.26 + * questions.
   10.27 + */
   10.28 +
   10.29 +package java.beans;
   10.30 +
   10.31 +/**
   10.32 + * A VetoableChange event gets fired whenever a bean changes a "constrained"
   10.33 + * property.  You can register a VetoableChangeListener with a source bean
   10.34 + * so as to be notified of any constrained property updates.
   10.35 + */
   10.36 +public interface VetoableChangeListener extends java.util.EventListener {
   10.37 +    /**
   10.38 +     * This method gets called when a constrained property is changed.
   10.39 +     *
   10.40 +     * @param     evt a <code>PropertyChangeEvent</code> object describing the
   10.41 +     *                event source and the property that has changed.
   10.42 +     * @exception PropertyVetoException if the recipient wishes the property
   10.43 +     *              change to be rolled back.
   10.44 +     */
   10.45 +    void vetoableChange(PropertyChangeEvent evt)
   10.46 +                                throws PropertyVetoException;
   10.47 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeListenerProxy.java	Tue Feb 05 17:04:22 2013 +0100
    11.3 @@ -0,0 +1,84 @@
    11.4 +/*
    11.5 + * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.  Oracle designates this
   11.11 + * particular file as subject to the "Classpath" exception as provided
   11.12 + * by Oracle in the LICENSE file that accompanied this code.
   11.13 + *
   11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.17 + * version 2 for more details (a copy is included in the LICENSE file that
   11.18 + * accompanied this code).
   11.19 + *
   11.20 + * You should have received a copy of the GNU General Public License version
   11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.23 + *
   11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.25 + * or visit www.oracle.com if you need additional information or have any
   11.26 + * questions.
   11.27 + */
   11.28 +
   11.29 +package java.beans;
   11.30 +
   11.31 +import java.util.EventListenerProxy;
   11.32 +
   11.33 +/**
   11.34 + * A class which extends the {@code EventListenerProxy}
   11.35 + * specifically for adding a {@code VetoableChangeListener}
   11.36 + * with a "constrained" property.
   11.37 + * Instances of this class can be added
   11.38 + * as {@code VetoableChangeListener}s to a bean
   11.39 + * which supports firing vetoable change events.
   11.40 + * <p>
   11.41 + * If the object has a {@code getVetoableChangeListeners} method
   11.42 + * then the array returned could be a mixture of {@code VetoableChangeListener}
   11.43 + * and {@code VetoableChangeListenerProxy} objects.
   11.44 + *
   11.45 + * @see java.util.EventListenerProxy
   11.46 + * @see VetoableChangeSupport#getVetoableChangeListeners
   11.47 + * @since 1.4
   11.48 + */
   11.49 +public class VetoableChangeListenerProxy
   11.50 +        extends EventListenerProxy<VetoableChangeListener>
   11.51 +        implements VetoableChangeListener {
   11.52 +
   11.53 +    private final String propertyName;
   11.54 +
   11.55 +    /**
   11.56 +     * Constructor which binds the {@code VetoableChangeListener}
   11.57 +     * to a specific property.
   11.58 +     *
   11.59 +     * @param propertyName  the name of the property to listen on
   11.60 +     * @param listener      the listener object
   11.61 +     */
   11.62 +    public VetoableChangeListenerProxy(String propertyName, VetoableChangeListener listener) {
   11.63 +        super(listener);
   11.64 +        this.propertyName = propertyName;
   11.65 +    }
   11.66 +
   11.67 +    /**
   11.68 +    * Forwards the property change event to the listener delegate.
   11.69 +    *
   11.70 +    * @param event  the property change event
   11.71 +    *
   11.72 +    * @exception PropertyVetoException if the recipient wishes the property
   11.73 +    *                                  change to be rolled back
   11.74 +    */
   11.75 +    public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException{
   11.76 +        getListener().vetoableChange(event);
   11.77 +    }
   11.78 +
   11.79 +    /**
   11.80 +     * Returns the name of the named property associated with the listener.
   11.81 +     *
   11.82 +     * @return the name of the named property associated with the listener
   11.83 +     */
   11.84 +    public String getPropertyName() {
   11.85 +        return this.propertyName;
   11.86 +    }
   11.87 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeSupport.java	Tue Feb 05 17:04:22 2013 +0100
    12.3 @@ -0,0 +1,526 @@
    12.4 +/*
    12.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.  Oracle designates this
   12.11 + * particular file as subject to the "Classpath" exception as provided
   12.12 + * by Oracle in the LICENSE file that accompanied this code.
   12.13 + *
   12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.17 + * version 2 for more details (a copy is included in the LICENSE file that
   12.18 + * accompanied this code).
   12.19 + *
   12.20 + * You should have received a copy of the GNU General Public License version
   12.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.23 + *
   12.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.25 + * or visit www.oracle.com if you need additional information or have any
   12.26 + * questions.
   12.27 + */
   12.28 +package java.beans;
   12.29 +
   12.30 +import java.io.Serializable;
   12.31 +import java.io.ObjectStreamField;
   12.32 +import java.io.ObjectOutputStream;
   12.33 +import java.io.ObjectInputStream;
   12.34 +import java.io.IOException;
   12.35 +import java.util.Hashtable;
   12.36 +import java.util.Map.Entry;
   12.37 +import org.apidesign.bck2brwsr.emul.lang.System;
   12.38 +
   12.39 +/**
   12.40 + * This is a utility class that can be used by beans that support constrained
   12.41 + * properties.  It manages a list of listeners and dispatches
   12.42 + * {@link PropertyChangeEvent}s to them.  You can use an instance of this class
   12.43 + * as a member field of your bean and delegate these types of work to it.
   12.44 + * The {@link VetoableChangeListener} can be registered for all properties
   12.45 + * or for a property specified by name.
   12.46 + * <p>
   12.47 + * Here is an example of {@code VetoableChangeSupport} usage that follows
   12.48 + * the rules and recommendations laid out in the JavaBeans&trade; specification:
   12.49 + * <pre>
   12.50 + * public class MyBean {
   12.51 + *     private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
   12.52 + *
   12.53 + *     public void addVetoableChangeListener(VetoableChangeListener listener) {
   12.54 + *         this.vcs.addVetoableChangeListener(listener);
   12.55 + *     }
   12.56 + *
   12.57 + *     public void removeVetoableChangeListener(VetoableChangeListener listener) {
   12.58 + *         this.vcs.removeVetoableChangeListener(listener);
   12.59 + *     }
   12.60 + *
   12.61 + *     private String value;
   12.62 + *
   12.63 + *     public String getValue() {
   12.64 + *         return this.value;
   12.65 + *     }
   12.66 + *
   12.67 + *     public void setValue(String newValue) throws PropertyVetoException {
   12.68 + *         String oldValue = this.value;
   12.69 + *         this.vcs.fireVetoableChange("value", oldValue, newValue);
   12.70 + *         this.value = newValue;
   12.71 + *     }
   12.72 + *
   12.73 + *     [...]
   12.74 + * }
   12.75 + * </pre>
   12.76 + * <p>
   12.77 + * A {@code VetoableChangeSupport} instance is thread-safe.
   12.78 + * <p>
   12.79 + * This class is serializable.  When it is serialized it will save
   12.80 + * (and restore) any listeners that are themselves serializable.  Any
   12.81 + * non-serializable listeners will be skipped during serialization.
   12.82 + *
   12.83 + * @see PropertyChangeSupport
   12.84 + */
   12.85 +public class VetoableChangeSupport implements Serializable {
   12.86 +    private VetoableChangeListenerMap map = new VetoableChangeListenerMap();
   12.87 +
   12.88 +    /**
   12.89 +     * Constructs a <code>VetoableChangeSupport</code> object.
   12.90 +     *
   12.91 +     * @param sourceBean  The bean to be given as the source for any events.
   12.92 +     */
   12.93 +    public VetoableChangeSupport(Object sourceBean) {
   12.94 +        if (sourceBean == null) {
   12.95 +            throw new NullPointerException();
   12.96 +        }
   12.97 +        source = sourceBean;
   12.98 +    }
   12.99 +
  12.100 +    /**
  12.101 +     * Add a VetoableChangeListener to the listener list.
  12.102 +     * The listener is registered for all properties.
  12.103 +     * The same listener object may be added more than once, and will be called
  12.104 +     * as many times as it is added.
  12.105 +     * If <code>listener</code> is null, no exception is thrown and no action
  12.106 +     * is taken.
  12.107 +     *
  12.108 +     * @param listener  The VetoableChangeListener to be added
  12.109 +     */
  12.110 +    public void addVetoableChangeListener(VetoableChangeListener listener) {
  12.111 +        if (listener == null) {
  12.112 +            return;
  12.113 +        }
  12.114 +        if (listener instanceof VetoableChangeListenerProxy) {
  12.115 +            VetoableChangeListenerProxy proxy =
  12.116 +                    (VetoableChangeListenerProxy)listener;
  12.117 +            // Call two argument add method.
  12.118 +            addVetoableChangeListener(proxy.getPropertyName(),
  12.119 +                                      proxy.getListener());
  12.120 +        } else {
  12.121 +            this.map.add(null, listener);
  12.122 +        }
  12.123 +    }
  12.124 +
  12.125 +    /**
  12.126 +     * Remove a VetoableChangeListener from the listener list.
  12.127 +     * This removes a VetoableChangeListener that was registered
  12.128 +     * for all properties.
  12.129 +     * If <code>listener</code> was added more than once to the same event
  12.130 +     * source, it will be notified one less time after being removed.
  12.131 +     * If <code>listener</code> is null, or was never added, no exception is
  12.132 +     * thrown and no action is taken.
  12.133 +     *
  12.134 +     * @param listener  The VetoableChangeListener to be removed
  12.135 +     */
  12.136 +    public void removeVetoableChangeListener(VetoableChangeListener listener) {
  12.137 +        if (listener == null) {
  12.138 +            return;
  12.139 +        }
  12.140 +        if (listener instanceof VetoableChangeListenerProxy) {
  12.141 +            VetoableChangeListenerProxy proxy =
  12.142 +                    (VetoableChangeListenerProxy)listener;
  12.143 +            // Call two argument remove method.
  12.144 +            removeVetoableChangeListener(proxy.getPropertyName(),
  12.145 +                                         proxy.getListener());
  12.146 +        } else {
  12.147 +            this.map.remove(null, listener);
  12.148 +        }
  12.149 +    }
  12.150 +
  12.151 +    /**
  12.152 +     * Returns an array of all the listeners that were added to the
  12.153 +     * VetoableChangeSupport object with addVetoableChangeListener().
  12.154 +     * <p>
  12.155 +     * If some listeners have been added with a named property, then
  12.156 +     * the returned array will be a mixture of VetoableChangeListeners
  12.157 +     * and <code>VetoableChangeListenerProxy</code>s. If the calling
  12.158 +     * method is interested in distinguishing the listeners then it must
  12.159 +     * test each element to see if it's a
  12.160 +     * <code>VetoableChangeListenerProxy</code>, perform the cast, and examine
  12.161 +     * the parameter.
  12.162 +     *
  12.163 +     * <pre>
  12.164 +     * VetoableChangeListener[] listeners = bean.getVetoableChangeListeners();
  12.165 +     * for (int i = 0; i < listeners.length; i++) {
  12.166 +     *        if (listeners[i] instanceof VetoableChangeListenerProxy) {
  12.167 +     *     VetoableChangeListenerProxy proxy =
  12.168 +     *                    (VetoableChangeListenerProxy)listeners[i];
  12.169 +     *     if (proxy.getPropertyName().equals("foo")) {
  12.170 +     *       // proxy is a VetoableChangeListener which was associated
  12.171 +     *       // with the property named "foo"
  12.172 +     *     }
  12.173 +     *   }
  12.174 +     * }
  12.175 +     *</pre>
  12.176 +     *
  12.177 +     * @see VetoableChangeListenerProxy
  12.178 +     * @return all of the <code>VetoableChangeListeners</code> added or an
  12.179 +     *         empty array if no listeners have been added
  12.180 +     * @since 1.4
  12.181 +     */
  12.182 +    public VetoableChangeListener[] getVetoableChangeListeners(){
  12.183 +        return this.map.getListeners();
  12.184 +    }
  12.185 +
  12.186 +    /**
  12.187 +     * Add a VetoableChangeListener for a specific property.  The listener
  12.188 +     * will be invoked only when a call on fireVetoableChange names that
  12.189 +     * specific property.
  12.190 +     * The same listener object may be added more than once.  For each
  12.191 +     * property,  the listener will be invoked the number of times it was added
  12.192 +     * for that property.
  12.193 +     * If <code>propertyName</code> or <code>listener</code> is null, no
  12.194 +     * exception is thrown and no action is taken.
  12.195 +     *
  12.196 +     * @param propertyName  The name of the property to listen on.
  12.197 +     * @param listener  The VetoableChangeListener to be added
  12.198 +     */
  12.199 +    public void addVetoableChangeListener(
  12.200 +                                String propertyName,
  12.201 +                VetoableChangeListener listener) {
  12.202 +        if (listener == null || propertyName == null) {
  12.203 +            return;
  12.204 +        }
  12.205 +        listener = this.map.extract(listener);
  12.206 +        if (listener != null) {
  12.207 +            this.map.add(propertyName, listener);
  12.208 +        }
  12.209 +    }
  12.210 +
  12.211 +    /**
  12.212 +     * Remove a VetoableChangeListener for a specific property.
  12.213 +     * If <code>listener</code> was added more than once to the same event
  12.214 +     * source for the specified property, it will be notified one less time
  12.215 +     * after being removed.
  12.216 +     * If <code>propertyName</code> is null, no exception is thrown and no
  12.217 +     * action is taken.
  12.218 +     * If <code>listener</code> is null, or was never added for the specified
  12.219 +     * property, no exception is thrown and no action is taken.
  12.220 +     *
  12.221 +     * @param propertyName  The name of the property that was listened on.
  12.222 +     * @param listener  The VetoableChangeListener to be removed
  12.223 +     */
  12.224 +    public void removeVetoableChangeListener(
  12.225 +                                String propertyName,
  12.226 +                VetoableChangeListener listener) {
  12.227 +        if (listener == null || propertyName == null) {
  12.228 +            return;
  12.229 +        }
  12.230 +        listener = this.map.extract(listener);
  12.231 +        if (listener != null) {
  12.232 +            this.map.remove(propertyName, listener);
  12.233 +        }
  12.234 +    }
  12.235 +
  12.236 +    /**
  12.237 +     * Returns an array of all the listeners which have been associated
  12.238 +     * with the named property.
  12.239 +     *
  12.240 +     * @param propertyName  The name of the property being listened to
  12.241 +     * @return all the <code>VetoableChangeListeners</code> associated with
  12.242 +     *         the named property.  If no such listeners have been added,
  12.243 +     *         or if <code>propertyName</code> is null, an empty array is
  12.244 +     *         returned.
  12.245 +     * @since 1.4
  12.246 +     */
  12.247 +    public VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
  12.248 +        return this.map.getListeners(propertyName);
  12.249 +    }
  12.250 +
  12.251 +    /**
  12.252 +     * Reports a constrained property update to listeners
  12.253 +     * that have been registered to track updates of
  12.254 +     * all properties or a property with the specified name.
  12.255 +     * <p>
  12.256 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.257 +     * If one of the listeners vetoes the update, this method passes
  12.258 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.259 +     * to all listeners that already confirmed this update
  12.260 +     * and throws the {@code PropertyVetoException} again.
  12.261 +     * <p>
  12.262 +     * No event is fired if old and new values are equal and non-null.
  12.263 +     * <p>
  12.264 +     * This is merely a convenience wrapper around the more general
  12.265 +     * {@link #fireVetoableChange(PropertyChangeEvent)} method.
  12.266 +     *
  12.267 +     * @param propertyName  the programmatic name of the property that is about to change
  12.268 +     * @param oldValue      the old value of the property
  12.269 +     * @param newValue      the new value of the property
  12.270 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.271 +     */
  12.272 +    public void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
  12.273 +            throws PropertyVetoException {
  12.274 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
  12.275 +            fireVetoableChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
  12.276 +        }
  12.277 +    }
  12.278 +
  12.279 +    /**
  12.280 +     * Reports an integer constrained property update to listeners
  12.281 +     * that have been registered to track updates of
  12.282 +     * all properties or a property with the specified name.
  12.283 +     * <p>
  12.284 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.285 +     * If one of the listeners vetoes the update, this method passes
  12.286 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.287 +     * to all listeners that already confirmed this update
  12.288 +     * and throws the {@code PropertyVetoException} again.
  12.289 +     * <p>
  12.290 +     * No event is fired if old and new values are equal.
  12.291 +     * <p>
  12.292 +     * This is merely a convenience wrapper around the more general
  12.293 +     * {@link #fireVetoableChange(String, Object, Object)} method.
  12.294 +     *
  12.295 +     * @param propertyName  the programmatic name of the property that is about to change
  12.296 +     * @param oldValue      the old value of the property
  12.297 +     * @param newValue      the new value of the property
  12.298 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.299 +     */
  12.300 +    public void fireVetoableChange(String propertyName, int oldValue, int newValue)
  12.301 +            throws PropertyVetoException {
  12.302 +        if (oldValue != newValue) {
  12.303 +            fireVetoableChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
  12.304 +        }
  12.305 +    }
  12.306 +
  12.307 +    /**
  12.308 +     * Reports a boolean constrained property update to listeners
  12.309 +     * that have been registered to track updates of
  12.310 +     * all properties or a property with the specified name.
  12.311 +     * <p>
  12.312 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.313 +     * If one of the listeners vetoes the update, this method passes
  12.314 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.315 +     * to all listeners that already confirmed this update
  12.316 +     * and throws the {@code PropertyVetoException} again.
  12.317 +     * <p>
  12.318 +     * No event is fired if old and new values are equal.
  12.319 +     * <p>
  12.320 +     * This is merely a convenience wrapper around the more general
  12.321 +     * {@link #fireVetoableChange(String, Object, Object)} method.
  12.322 +     *
  12.323 +     * @param propertyName  the programmatic name of the property that is about to change
  12.324 +     * @param oldValue      the old value of the property
  12.325 +     * @param newValue      the new value of the property
  12.326 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.327 +     */
  12.328 +    public void fireVetoableChange(String propertyName, boolean oldValue, boolean newValue)
  12.329 +            throws PropertyVetoException {
  12.330 +        if (oldValue != newValue) {
  12.331 +            fireVetoableChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
  12.332 +        }
  12.333 +    }
  12.334 +
  12.335 +    /**
  12.336 +     * Fires a property change event to listeners
  12.337 +     * that have been registered to track updates of
  12.338 +     * all properties or a property with the specified name.
  12.339 +     * <p>
  12.340 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.341 +     * If one of the listeners vetoes the update, this method passes
  12.342 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.343 +     * to all listeners that already confirmed this update
  12.344 +     * and throws the {@code PropertyVetoException} again.
  12.345 +     * <p>
  12.346 +     * No event is fired if the given event's old and new values are equal and non-null.
  12.347 +     *
  12.348 +     * @param event  the {@code PropertyChangeEvent} to be fired
  12.349 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.350 +     */
  12.351 +    public void fireVetoableChange(PropertyChangeEvent event)
  12.352 +            throws PropertyVetoException {
  12.353 +        Object oldValue = event.getOldValue();
  12.354 +        Object newValue = event.getNewValue();
  12.355 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
  12.356 +            String name = event.getPropertyName();
  12.357 +
  12.358 +            VetoableChangeListener[] common = this.map.get(null);
  12.359 +            VetoableChangeListener[] named = (name != null)
  12.360 +                        ? this.map.get(name)
  12.361 +                        : null;
  12.362 +
  12.363 +            VetoableChangeListener[] listeners;
  12.364 +            if (common == null) {
  12.365 +                listeners = named;
  12.366 +            }
  12.367 +            else if (named == null) {
  12.368 +                listeners = common;
  12.369 +            }
  12.370 +            else {
  12.371 +                listeners = new VetoableChangeListener[common.length + named.length];
  12.372 +                System.arraycopy(common, 0, listeners, 0, common.length);
  12.373 +                System.arraycopy(named, 0, listeners, common.length, named.length);
  12.374 +            }
  12.375 +            if (listeners != null) {
  12.376 +                int current = 0;
  12.377 +                try {
  12.378 +                    while (current < listeners.length) {
  12.379 +                        listeners[current].vetoableChange(event);
  12.380 +                        current++;
  12.381 +                    }
  12.382 +                }
  12.383 +                catch (PropertyVetoException veto) {
  12.384 +                    event = new PropertyChangeEvent(this.source, name, newValue, oldValue);
  12.385 +                    for (int i = 0; i < current; i++) {
  12.386 +                        try {
  12.387 +                            listeners[i].vetoableChange(event);
  12.388 +                        }
  12.389 +                        catch (PropertyVetoException exception) {
  12.390 +                            // ignore exceptions that occur during rolling back
  12.391 +                        }
  12.392 +                    }
  12.393 +                    throw veto; // rethrow the veto exception
  12.394 +                }
  12.395 +            }
  12.396 +        }
  12.397 +    }
  12.398 +
  12.399 +    /**
  12.400 +     * Check if there are any listeners for a specific property, including
  12.401 +     * those registered on all properties.  If <code>propertyName</code>
  12.402 +     * is null, only check for listeners registered on all properties.
  12.403 +     *
  12.404 +     * @param propertyName  the property name.
  12.405 +     * @return true if there are one or more listeners for the given property
  12.406 +     */
  12.407 +    public boolean hasListeners(String propertyName) {
  12.408 +        return this.map.hasListeners(propertyName);
  12.409 +    }
  12.410 +
  12.411 +    /**
  12.412 +     * @serialData Null terminated list of <code>VetoableChangeListeners</code>.
  12.413 +     * <p>
  12.414 +     * At serialization time we skip non-serializable listeners and
  12.415 +     * only serialize the serializable listeners.
  12.416 +     */
  12.417 +    private void writeObject(ObjectOutputStream s) throws IOException {
  12.418 +        Hashtable<String, VetoableChangeSupport> children = null;
  12.419 +        VetoableChangeListener[] listeners = null;
  12.420 +        synchronized (this.map) {
  12.421 +            for (Entry<String, VetoableChangeListener[]> entry : this.map.getEntries()) {
  12.422 +                String property = entry.getKey();
  12.423 +                if (property == null) {
  12.424 +                    listeners = entry.getValue();
  12.425 +                } else {
  12.426 +                    if (children == null) {
  12.427 +                        children = new Hashtable<String, VetoableChangeSupport>();
  12.428 +                    }
  12.429 +                    VetoableChangeSupport vcs = new VetoableChangeSupport(this.source);
  12.430 +                    vcs.map.set(null, entry.getValue());
  12.431 +                    children.put(property, vcs);
  12.432 +                }
  12.433 +            }
  12.434 +        }
  12.435 +        ObjectOutputStream.PutField fields = s.putFields();
  12.436 +        fields.put("children", children);
  12.437 +        fields.put("source", this.source);
  12.438 +        fields.put("vetoableChangeSupportSerializedDataVersion", 2);
  12.439 +        s.writeFields();
  12.440 +
  12.441 +        if (listeners != null) {
  12.442 +            for (VetoableChangeListener l : listeners) {
  12.443 +                if (l instanceof Serializable) {
  12.444 +                    s.writeObject(l);
  12.445 +                }
  12.446 +            }
  12.447 +        }
  12.448 +        s.writeObject(null);
  12.449 +    }
  12.450 +
  12.451 +    private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
  12.452 +        this.map = new VetoableChangeListenerMap();
  12.453 +
  12.454 +        ObjectInputStream.GetField fields = s.readFields();
  12.455 +
  12.456 +        Hashtable<String, VetoableChangeSupport> children = (Hashtable<String, VetoableChangeSupport>) fields.get("children", null);
  12.457 +        this.source = fields.get("source", null);
  12.458 +        fields.get("vetoableChangeSupportSerializedDataVersion", 2);
  12.459 +
  12.460 +        Object listenerOrNull;
  12.461 +        while (null != (listenerOrNull = s.readObject())) {
  12.462 +            this.map.add(null, (VetoableChangeListener)listenerOrNull);
  12.463 +        }
  12.464 +        if (children != null) {
  12.465 +            for (Entry<String, VetoableChangeSupport> entry : children.entrySet()) {
  12.466 +                for (VetoableChangeListener listener : entry.getValue().getVetoableChangeListeners()) {
  12.467 +                    this.map.add(entry.getKey(), listener);
  12.468 +                }
  12.469 +            }
  12.470 +        }
  12.471 +    }
  12.472 +
  12.473 +    /**
  12.474 +     * The object to be provided as the "source" for any generated events.
  12.475 +     */
  12.476 +    private Object source;
  12.477 +
  12.478 +    /**
  12.479 +     * @serialField children                                   Hashtable
  12.480 +     * @serialField source                                     Object
  12.481 +     * @serialField vetoableChangeSupportSerializedDataVersion int
  12.482 +     */
  12.483 +    private static final ObjectStreamField[] serialPersistentFields = {
  12.484 +            new ObjectStreamField("children", Hashtable.class),
  12.485 +            new ObjectStreamField("source", Object.class),
  12.486 +            new ObjectStreamField("vetoableChangeSupportSerializedDataVersion", Integer.TYPE)
  12.487 +    };
  12.488 +
  12.489 +    /**
  12.490 +     * Serialization version ID, so we're compatible with JDK 1.1
  12.491 +     */
  12.492 +    static final long serialVersionUID = -5090210921595982017L;
  12.493 +
  12.494 +    /**
  12.495 +     * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
  12.496 +     * that works with {@link VetoableChangeListener VetoableChangeListener} objects.
  12.497 +     */
  12.498 +    private static final class VetoableChangeListenerMap extends ChangeListenerMap<VetoableChangeListener> {
  12.499 +        private static final VetoableChangeListener[] EMPTY = {};
  12.500 +
  12.501 +        /**
  12.502 +         * Creates an array of {@link VetoableChangeListener VetoableChangeListener} objects.
  12.503 +         * This method uses the same instance of the empty array
  12.504 +         * when {@code length} equals {@code 0}.
  12.505 +         *
  12.506 +         * @param length  the array length
  12.507 +         * @return        an array with specified length
  12.508 +         */
  12.509 +        @Override
  12.510 +        protected VetoableChangeListener[] newArray(int length) {
  12.511 +            return (0 < length)
  12.512 +                    ? new VetoableChangeListener[length]
  12.513 +                    : EMPTY;
  12.514 +        }
  12.515 +
  12.516 +        /**
  12.517 +         * Creates a {@link VetoableChangeListenerProxy VetoableChangeListenerProxy}
  12.518 +         * object for the specified property.
  12.519 +         *
  12.520 +         * @param name      the name of the property to listen on
  12.521 +         * @param listener  the listener to process events
  12.522 +         * @return          a {@code VetoableChangeListenerProxy} object
  12.523 +         */
  12.524 +        @Override
  12.525 +        protected VetoableChangeListener newProxy(String name, VetoableChangeListener listener) {
  12.526 +            return new VetoableChangeListenerProxy(name, listener);
  12.527 +        }
  12.528 +    }
  12.529 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/emul/compact/src/main/java/java/io/Bits.java	Tue Feb 05 17:04:22 2013 +0100
    13.3 @@ -0,0 +1,123 @@
    13.4 +/*
    13.5 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.  Oracle designates this
   13.11 + * particular file as subject to the "Classpath" exception as provided
   13.12 + * by Oracle in the LICENSE file that accompanied this code.
   13.13 + *
   13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 + * version 2 for more details (a copy is included in the LICENSE file that
   13.18 + * accompanied this code).
   13.19 + *
   13.20 + * You should have received a copy of the GNU General Public License version
   13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 + *
   13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.25 + * or visit www.oracle.com if you need additional information or have any
   13.26 + * questions.
   13.27 + */
   13.28 +
   13.29 +package java.io;
   13.30 +
   13.31 +/**
   13.32 + * Utility methods for packing/unpacking primitive values in/out of byte arrays
   13.33 + * using big-endian byte ordering.
   13.34 + */
   13.35 +class Bits {
   13.36 +
   13.37 +    /*
   13.38 +     * Methods for unpacking primitive values from byte arrays starting at
   13.39 +     * given offsets.
   13.40 +     */
   13.41 +
   13.42 +    static boolean getBoolean(byte[] b, int off) {
   13.43 +        return b[off] != 0;
   13.44 +    }
   13.45 +
   13.46 +    static char getChar(byte[] b, int off) {
   13.47 +        return (char) ((b[off + 1] & 0xFF) +
   13.48 +                       (b[off] << 8));
   13.49 +    }
   13.50 +
   13.51 +    static short getShort(byte[] b, int off) {
   13.52 +        return (short) ((b[off + 1] & 0xFF) +
   13.53 +                        (b[off] << 8));
   13.54 +    }
   13.55 +
   13.56 +    static int getInt(byte[] b, int off) {
   13.57 +        return ((b[off + 3] & 0xFF)      ) +
   13.58 +               ((b[off + 2] & 0xFF) <<  8) +
   13.59 +               ((b[off + 1] & 0xFF) << 16) +
   13.60 +               ((b[off    ]       ) << 24);
   13.61 +    }
   13.62 +
   13.63 +    static float getFloat(byte[] b, int off) {
   13.64 +        return Float.intBitsToFloat(getInt(b, off));
   13.65 +    }
   13.66 +
   13.67 +    static long getLong(byte[] b, int off) {
   13.68 +        return ((b[off + 7] & 0xFFL)      ) +
   13.69 +               ((b[off + 6] & 0xFFL) <<  8) +
   13.70 +               ((b[off + 5] & 0xFFL) << 16) +
   13.71 +               ((b[off + 4] & 0xFFL) << 24) +
   13.72 +               ((b[off + 3] & 0xFFL) << 32) +
   13.73 +               ((b[off + 2] & 0xFFL) << 40) +
   13.74 +               ((b[off + 1] & 0xFFL) << 48) +
   13.75 +               (((long) b[off])      << 56);
   13.76 +    }
   13.77 +
   13.78 +    static double getDouble(byte[] b, int off) {
   13.79 +        return Double.longBitsToDouble(getLong(b, off));
   13.80 +    }
   13.81 +
   13.82 +    /*
   13.83 +     * Methods for packing primitive values into byte arrays starting at given
   13.84 +     * offsets.
   13.85 +     */
   13.86 +
   13.87 +    static void putBoolean(byte[] b, int off, boolean val) {
   13.88 +        b[off] = (byte) (val ? 1 : 0);
   13.89 +    }
   13.90 +
   13.91 +    static void putChar(byte[] b, int off, char val) {
   13.92 +        b[off + 1] = (byte) (val      );
   13.93 +        b[off    ] = (byte) (val >>> 8);
   13.94 +    }
   13.95 +
   13.96 +    static void putShort(byte[] b, int off, short val) {
   13.97 +        b[off + 1] = (byte) (val      );
   13.98 +        b[off    ] = (byte) (val >>> 8);
   13.99 +    }
  13.100 +
  13.101 +    static void putInt(byte[] b, int off, int val) {
  13.102 +        b[off + 3] = (byte) (val       );
  13.103 +        b[off + 2] = (byte) (val >>>  8);
  13.104 +        b[off + 1] = (byte) (val >>> 16);
  13.105 +        b[off    ] = (byte) (val >>> 24);
  13.106 +    }
  13.107 +
  13.108 +    static void putFloat(byte[] b, int off, float val) {
  13.109 +        putInt(b, off,  Float.floatToIntBits(val));
  13.110 +    }
  13.111 +
  13.112 +    static void putLong(byte[] b, int off, long val) {
  13.113 +        b[off + 7] = (byte) (val       );
  13.114 +        b[off + 6] = (byte) (val >>>  8);
  13.115 +        b[off + 5] = (byte) (val >>> 16);
  13.116 +        b[off + 4] = (byte) (val >>> 24);
  13.117 +        b[off + 3] = (byte) (val >>> 32);
  13.118 +        b[off + 2] = (byte) (val >>> 40);
  13.119 +        b[off + 1] = (byte) (val >>> 48);
  13.120 +        b[off    ] = (byte) (val >>> 56);
  13.121 +    }
  13.122 +
  13.123 +    static void putDouble(byte[] b, int off, double val) {
  13.124 +        putLong(b, off, Double.doubleToLongBits(val));
  13.125 +    }
  13.126 +}
    14.1 --- a/emul/compact/src/main/java/java/io/BufferedReader.java	Tue Feb 05 16:40:01 2013 +0100
    14.2 +++ b/emul/compact/src/main/java/java/io/BufferedReader.java	Tue Feb 05 17:04:22 2013 +0100
    14.3 @@ -25,7 +25,6 @@
    14.4  
    14.5  package java.io;
    14.6  
    14.7 -import org.apidesign.bck2brwsr.emul.lang.System;
    14.8  
    14.9  
   14.10  /**
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/emul/compact/src/main/java/java/io/DataOutput.java	Tue Feb 05 17:04:22 2013 +0100
    15.3 @@ -0,0 +1,354 @@
    15.4 +/*
    15.5 + * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.  Oracle designates this
   15.11 + * particular file as subject to the "Classpath" exception as provided
   15.12 + * by Oracle in the LICENSE file that accompanied this code.
   15.13 + *
   15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.17 + * version 2 for more details (a copy is included in the LICENSE file that
   15.18 + * accompanied this code).
   15.19 + *
   15.20 + * You should have received a copy of the GNU General Public License version
   15.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.23 + *
   15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.25 + * or visit www.oracle.com if you need additional information or have any
   15.26 + * questions.
   15.27 + */
   15.28 +
   15.29 +package java.io;
   15.30 +
   15.31 +/**
   15.32 + * The <code>DataOutput</code> interface provides
   15.33 + * for converting data from any of the Java
   15.34 + * primitive types to a series of bytes and
   15.35 + * writing these bytes to a binary stream.
   15.36 + * There is  also a facility for converting
   15.37 + * a <code>String</code> into
   15.38 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
   15.39 + * format and writing the resulting series
   15.40 + * of bytes.
   15.41 + * <p>
   15.42 + * For all the methods in this interface that
   15.43 + * write bytes, it is generally true that if
   15.44 + * a byte cannot be written for any reason,
   15.45 + * an <code>IOException</code> is thrown.
   15.46 + *
   15.47 + * @author  Frank Yellin
   15.48 + * @see     java.io.DataInput
   15.49 + * @see     java.io.DataOutputStream
   15.50 + * @since   JDK1.0
   15.51 + */
   15.52 +public
   15.53 +interface DataOutput {
   15.54 +    /**
   15.55 +     * Writes to the output stream the eight
   15.56 +     * low-order bits of the argument <code>b</code>.
   15.57 +     * The 24 high-order  bits of <code>b</code>
   15.58 +     * are ignored.
   15.59 +     *
   15.60 +     * @param      b   the byte to be written.
   15.61 +     * @throws     IOException  if an I/O error occurs.
   15.62 +     */
   15.63 +    void write(int b) throws IOException;
   15.64 +
   15.65 +    /**
   15.66 +     * Writes to the output stream all the bytes in array <code>b</code>.
   15.67 +     * If <code>b</code> is <code>null</code>,
   15.68 +     * a <code>NullPointerException</code> is thrown.
   15.69 +     * If <code>b.length</code> is zero, then
   15.70 +     * no bytes are written. Otherwise, the byte
   15.71 +     * <code>b[0]</code> is written first, then
   15.72 +     * <code>b[1]</code>, and so on; the last byte
   15.73 +     * written is <code>b[b.length-1]</code>.
   15.74 +     *
   15.75 +     * @param      b   the data.
   15.76 +     * @throws     IOException  if an I/O error occurs.
   15.77 +     */
   15.78 +    void write(byte b[]) throws IOException;
   15.79 +
   15.80 +    /**
   15.81 +     * Writes <code>len</code> bytes from array
   15.82 +     * <code>b</code>, in order,  to
   15.83 +     * the output stream.  If <code>b</code>
   15.84 +     * is <code>null</code>, a <code>NullPointerException</code>
   15.85 +     * is thrown.  If <code>off</code> is negative,
   15.86 +     * or <code>len</code> is negative, or <code>off+len</code>
   15.87 +     * is greater than the length of the array
   15.88 +     * <code>b</code>, then an <code>IndexOutOfBoundsException</code>
   15.89 +     * is thrown.  If <code>len</code> is zero,
   15.90 +     * then no bytes are written. Otherwise, the
   15.91 +     * byte <code>b[off]</code> is written first,
   15.92 +     * then <code>b[off+1]</code>, and so on; the
   15.93 +     * last byte written is <code>b[off+len-1]</code>.
   15.94 +     *
   15.95 +     * @param      b     the data.
   15.96 +     * @param      off   the start offset in the data.
   15.97 +     * @param      len   the number of bytes to write.
   15.98 +     * @throws     IOException  if an I/O error occurs.
   15.99 +     */
  15.100 +    void write(byte b[], int off, int len) throws IOException;
  15.101 +
  15.102 +    /**
  15.103 +     * Writes a <code>boolean</code> value to this output stream.
  15.104 +     * If the argument <code>v</code>
  15.105 +     * is <code>true</code>, the value <code>(byte)1</code>
  15.106 +     * is written; if <code>v</code> is <code>false</code>,
  15.107 +     * the  value <code>(byte)0</code> is written.
  15.108 +     * The byte written by this method may
  15.109 +     * be read by the <code>readBoolean</code>
  15.110 +     * method of interface <code>DataInput</code>,
  15.111 +     * which will then return a <code>boolean</code>
  15.112 +     * equal to <code>v</code>.
  15.113 +     *
  15.114 +     * @param      v   the boolean to be written.
  15.115 +     * @throws     IOException  if an I/O error occurs.
  15.116 +     */
  15.117 +    void writeBoolean(boolean v) throws IOException;
  15.118 +
  15.119 +    /**
  15.120 +     * Writes to the output stream the eight low-
  15.121 +     * order bits of the argument <code>v</code>.
  15.122 +     * The 24 high-order bits of <code>v</code>
  15.123 +     * are ignored. (This means  that <code>writeByte</code>
  15.124 +     * does exactly the same thing as <code>write</code>
  15.125 +     * for an integer argument.) The byte written
  15.126 +     * by this method may be read by the <code>readByte</code>
  15.127 +     * method of interface <code>DataInput</code>,
  15.128 +     * which will then return a <code>byte</code>
  15.129 +     * equal to <code>(byte)v</code>.
  15.130 +     *
  15.131 +     * @param      v   the byte value to be written.
  15.132 +     * @throws     IOException  if an I/O error occurs.
  15.133 +     */
  15.134 +    void writeByte(int v) throws IOException;
  15.135 +
  15.136 +    /**
  15.137 +     * Writes two bytes to the output
  15.138 +     * stream to represent the value of the argument.
  15.139 +     * The byte values to be written, in the  order
  15.140 +     * shown, are: <p>
  15.141 +     * <pre><code>
  15.142 +     * (byte)(0xff &amp; (v &gt;&gt; 8))
  15.143 +     * (byte)(0xff &amp; v)
  15.144 +     * </code> </pre> <p>
  15.145 +     * The bytes written by this method may be
  15.146 +     * read by the <code>readShort</code> method
  15.147 +     * of interface <code>DataInput</code> , which
  15.148 +     * will then return a <code>short</code> equal
  15.149 +     * to <code>(short)v</code>.
  15.150 +     *
  15.151 +     * @param      v   the <code>short</code> value to be written.
  15.152 +     * @throws     IOException  if an I/O error occurs.
  15.153 +     */
  15.154 +    void writeShort(int v) throws IOException;
  15.155 +
  15.156 +    /**
  15.157 +     * Writes a <code>char</code> value, which
  15.158 +     * is comprised of two bytes, to the
  15.159 +     * output stream.
  15.160 +     * The byte values to be written, in the  order
  15.161 +     * shown, are:
  15.162 +     * <p><pre><code>
  15.163 +     * (byte)(0xff &amp; (v &gt;&gt; 8))
  15.164 +     * (byte)(0xff &amp; v)
  15.165 +     * </code></pre><p>
  15.166 +     * The bytes written by this method may be
  15.167 +     * read by the <code>readChar</code> method
  15.168 +     * of interface <code>DataInput</code> , which
  15.169 +     * will then return a <code>char</code> equal
  15.170 +     * to <code>(char)v</code>.
  15.171 +     *
  15.172 +     * @param      v   the <code>char</code> value to be written.
  15.173 +     * @throws     IOException  if an I/O error occurs.
  15.174 +     */
  15.175 +    void writeChar(int v) throws IOException;
  15.176 +
  15.177 +    /**
  15.178 +     * Writes an <code>int</code> value, which is
  15.179 +     * comprised of four bytes, to the output stream.
  15.180 +     * The byte values to be written, in the  order
  15.181 +     * shown, are:
  15.182 +     * <p><pre><code>
  15.183 +     * (byte)(0xff &amp; (v &gt;&gt; 24))
  15.184 +     * (byte)(0xff &amp; (v &gt;&gt; 16))
  15.185 +     * (byte)(0xff &amp; (v &gt;&gt; &#32; &#32;8))
  15.186 +     * (byte)(0xff &amp; v)
  15.187 +     * </code></pre><p>
  15.188 +     * The bytes written by this method may be read
  15.189 +     * by the <code>readInt</code> method of interface
  15.190 +     * <code>DataInput</code> , which will then
  15.191 +     * return an <code>int</code> equal to <code>v</code>.
  15.192 +     *
  15.193 +     * @param      v   the <code>int</code> value to be written.
  15.194 +     * @throws     IOException  if an I/O error occurs.
  15.195 +     */
  15.196 +    void writeInt(int v) throws IOException;
  15.197 +
  15.198 +    /**
  15.199 +     * Writes a <code>long</code> value, which is
  15.200 +     * comprised of eight bytes, to the output stream.
  15.201 +     * The byte values to be written, in the  order
  15.202 +     * shown, are:
  15.203 +     * <p><pre><code>
  15.204 +     * (byte)(0xff &amp; (v &gt;&gt; 56))
  15.205 +     * (byte)(0xff &amp; (v &gt;&gt; 48))
  15.206 +     * (byte)(0xff &amp; (v &gt;&gt; 40))
  15.207 +     * (byte)(0xff &amp; (v &gt;&gt; 32))
  15.208 +     * (byte)(0xff &amp; (v &gt;&gt; 24))
  15.209 +     * (byte)(0xff &amp; (v &gt;&gt; 16))
  15.210 +     * (byte)(0xff &amp; (v &gt;&gt;  8))
  15.211 +     * (byte)(0xff &amp; v)
  15.212 +     * </code></pre><p>
  15.213 +     * The bytes written by this method may be
  15.214 +     * read by the <code>readLong</code> method
  15.215 +     * of interface <code>DataInput</code> , which
  15.216 +     * will then return a <code>long</code> equal
  15.217 +     * to <code>v</code>.
  15.218 +     *
  15.219 +     * @param      v   the <code>long</code> value to be written.
  15.220 +     * @throws     IOException  if an I/O error occurs.
  15.221 +     */
  15.222 +    void writeLong(long v) throws IOException;
  15.223 +
  15.224 +    /**
  15.225 +     * Writes a <code>float</code> value,
  15.226 +     * which is comprised of four bytes, to the output stream.
  15.227 +     * It does this as if it first converts this
  15.228 +     * <code>float</code> value to an <code>int</code>
  15.229 +     * in exactly the manner of the <code>Float.floatToIntBits</code>
  15.230 +     * method  and then writes the <code>int</code>
  15.231 +     * value in exactly the manner of the  <code>writeInt</code>
  15.232 +     * method.  The bytes written by this method
  15.233 +     * may be read by the <code>readFloat</code>
  15.234 +     * method of interface <code>DataInput</code>,
  15.235 +     * which will then return a <code>float</code>
  15.236 +     * equal to <code>v</code>.
  15.237 +     *
  15.238 +     * @param      v   the <code>float</code> value to be written.
  15.239 +     * @throws     IOException  if an I/O error occurs.
  15.240 +     */
  15.241 +    void writeFloat(float v) throws IOException;
  15.242 +
  15.243 +    /**
  15.244 +     * Writes a <code>double</code> value,
  15.245 +     * which is comprised of eight bytes, to the output stream.
  15.246 +     * It does this as if it first converts this
  15.247 +     * <code>double</code> value to a <code>long</code>
  15.248 +     * in exactly the manner of the <code>Double.doubleToLongBits</code>
  15.249 +     * method  and then writes the <code>long</code>
  15.250 +     * value in exactly the manner of the  <code>writeLong</code>
  15.251 +     * method. The bytes written by this method
  15.252 +     * may be read by the <code>readDouble</code>
  15.253 +     * method of interface <code>DataInput</code>,
  15.254 +     * which will then return a <code>double</code>
  15.255 +     * equal to <code>v</code>.
  15.256 +     *
  15.257 +     * @param      v   the <code>double</code> value to be written.
  15.258 +     * @throws     IOException  if an I/O error occurs.
  15.259 +     */
  15.260 +    void writeDouble(double v) throws IOException;
  15.261 +
  15.262 +    /**
  15.263 +     * Writes a string to the output stream.
  15.264 +     * For every character in the string
  15.265 +     * <code>s</code>,  taken in order, one byte
  15.266 +     * is written to the output stream.  If
  15.267 +     * <code>s</code> is <code>null</code>, a <code>NullPointerException</code>
  15.268 +     * is thrown.<p>  If <code>s.length</code>
  15.269 +     * is zero, then no bytes are written. Otherwise,
  15.270 +     * the character <code>s[0]</code> is written
  15.271 +     * first, then <code>s[1]</code>, and so on;
  15.272 +     * the last character written is <code>s[s.length-1]</code>.
  15.273 +     * For each character, one byte is written,
  15.274 +     * the low-order byte, in exactly the manner
  15.275 +     * of the <code>writeByte</code> method . The
  15.276 +     * high-order eight bits of each character
  15.277 +     * in the string are ignored.
  15.278 +     *
  15.279 +     * @param      s   the string of bytes to be written.
  15.280 +     * @throws     IOException  if an I/O error occurs.
  15.281 +     */
  15.282 +    void writeBytes(String s) throws IOException;
  15.283 +
  15.284 +    /**
  15.285 +     * Writes every character in the string <code>s</code>,
  15.286 +     * to the output stream, in order,
  15.287 +     * two bytes per character. If <code>s</code>
  15.288 +     * is <code>null</code>, a <code>NullPointerException</code>
  15.289 +     * is thrown.  If <code>s.length</code>
  15.290 +     * is zero, then no characters are written.
  15.291 +     * Otherwise, the character <code>s[0]</code>
  15.292 +     * is written first, then <code>s[1]</code>,
  15.293 +     * and so on; the last character written is
  15.294 +     * <code>s[s.length-1]</code>. For each character,
  15.295 +     * two bytes are actually written, high-order
  15.296 +     * byte first, in exactly the manner of the
  15.297 +     * <code>writeChar</code> method.
  15.298 +     *
  15.299 +     * @param      s   the string value to be written.
  15.300 +     * @throws     IOException  if an I/O error occurs.
  15.301 +     */
  15.302 +    void writeChars(String s) throws IOException;
  15.303 +
  15.304 +    /**
  15.305 +     * Writes two bytes of length information
  15.306 +     * to the output stream, followed
  15.307 +     * by the
  15.308 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  15.309 +     * representation
  15.310 +     * of  every character in the string <code>s</code>.
  15.311 +     * If <code>s</code> is <code>null</code>,
  15.312 +     * a <code>NullPointerException</code> is thrown.
  15.313 +     * Each character in the string <code>s</code>
  15.314 +     * is converted to a group of one, two, or
  15.315 +     * three bytes, depending on the value of the
  15.316 +     * character.<p>
  15.317 +     * If a character <code>c</code>
  15.318 +     * is in the range <code>&#92;u0001</code> through
  15.319 +     * <code>&#92;u007f</code>, it is represented
  15.320 +     * by one byte:<p>
  15.321 +     * <pre>(byte)c </pre>  <p>
  15.322 +     * If a character <code>c</code> is <code>&#92;u0000</code>
  15.323 +     * or is in the range <code>&#92;u0080</code>
  15.324 +     * through <code>&#92;u07ff</code>, then it is
  15.325 +     * represented by two bytes, to be written
  15.326 +     * in the order shown:<p> <pre><code>
  15.327 +     * (byte)(0xc0 | (0x1f &amp; (c &gt;&gt; 6)))
  15.328 +     * (byte)(0x80 | (0x3f &amp; c))
  15.329 +     *  </code></pre>  <p> If a character
  15.330 +     * <code>c</code> is in the range <code>&#92;u0800</code>
  15.331 +     * through <code>uffff</code>, then it is
  15.332 +     * represented by three bytes, to be written
  15.333 +     * in the order shown:<p> <pre><code>
  15.334 +     * (byte)(0xe0 | (0x0f &amp; (c &gt;&gt; 12)))
  15.335 +     * (byte)(0x80 | (0x3f &amp; (c &gt;&gt;  6)))
  15.336 +     * (byte)(0x80 | (0x3f &amp; c))
  15.337 +     *  </code></pre>  <p> First,
  15.338 +     * the total number of bytes needed to represent
  15.339 +     * all the characters of <code>s</code> is
  15.340 +     * calculated. If this number is larger than
  15.341 +     * <code>65535</code>, then a <code>UTFDataFormatException</code>
  15.342 +     * is thrown. Otherwise, this length is written
  15.343 +     * to the output stream in exactly the manner
  15.344 +     * of the <code>writeShort</code> method;
  15.345 +     * after this, the one-, two-, or three-byte
  15.346 +     * representation of each character in the
  15.347 +     * string <code>s</code> is written.<p>  The
  15.348 +     * bytes written by this method may be read
  15.349 +     * by the <code>readUTF</code> method of interface
  15.350 +     * <code>DataInput</code> , which will then
  15.351 +     * return a <code>String</code> equal to <code>s</code>.
  15.352 +     *
  15.353 +     * @param      s   the string value to be written.
  15.354 +     * @throws     IOException  if an I/O error occurs.
  15.355 +     */
  15.356 +    void writeUTF(String s) throws IOException;
  15.357 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/emul/compact/src/main/java/java/io/DataOutputStream.java	Tue Feb 05 17:04:22 2013 +0100
    16.3 @@ -0,0 +1,416 @@
    16.4 +/*
    16.5 + * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.  Oracle designates this
   16.11 + * particular file as subject to the "Classpath" exception as provided
   16.12 + * by Oracle in the LICENSE file that accompanied this code.
   16.13 + *
   16.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.17 + * version 2 for more details (a copy is included in the LICENSE file that
   16.18 + * accompanied this code).
   16.19 + *
   16.20 + * You should have received a copy of the GNU General Public License version
   16.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.23 + *
   16.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.25 + * or visit www.oracle.com if you need additional information or have any
   16.26 + * questions.
   16.27 + */
   16.28 +
   16.29 +package java.io;
   16.30 +
   16.31 +/**
   16.32 + * A data output stream lets an application write primitive Java data
   16.33 + * types to an output stream in a portable way. An application can
   16.34 + * then use a data input stream to read the data back in.
   16.35 + *
   16.36 + * @author  unascribed
   16.37 + * @see     java.io.DataInputStream
   16.38 + * @since   JDK1.0
   16.39 + */
   16.40 +public
   16.41 +class DataOutputStream extends FilterOutputStream implements DataOutput {
   16.42 +    /**
   16.43 +     * The number of bytes written to the data output stream so far.
   16.44 +     * If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
   16.45 +     */
   16.46 +    protected int written;
   16.47 +
   16.48 +    /**
   16.49 +     * bytearr is initialized on demand by writeUTF
   16.50 +     */
   16.51 +    private byte[] bytearr = null;
   16.52 +
   16.53 +    /**
   16.54 +     * Creates a new data output stream to write data to the specified
   16.55 +     * underlying output stream. The counter <code>written</code> is
   16.56 +     * set to zero.
   16.57 +     *
   16.58 +     * @param   out   the underlying output stream, to be saved for later
   16.59 +     *                use.
   16.60 +     * @see     java.io.FilterOutputStream#out
   16.61 +     */
   16.62 +    public DataOutputStream(OutputStream out) {
   16.63 +        super(out);
   16.64 +    }
   16.65 +
   16.66 +    /**
   16.67 +     * Increases the written counter by the specified value
   16.68 +     * until it reaches Integer.MAX_VALUE.
   16.69 +     */
   16.70 +    private void incCount(int value) {
   16.71 +        int temp = written + value;
   16.72 +        if (temp < 0) {
   16.73 +            temp = Integer.MAX_VALUE;
   16.74 +        }
   16.75 +        written = temp;
   16.76 +    }
   16.77 +
   16.78 +    /**
   16.79 +     * Writes the specified byte (the low eight bits of the argument
   16.80 +     * <code>b</code>) to the underlying output stream. If no exception
   16.81 +     * is thrown, the counter <code>written</code> is incremented by
   16.82 +     * <code>1</code>.
   16.83 +     * <p>
   16.84 +     * Implements the <code>write</code> method of <code>OutputStream</code>.
   16.85 +     *
   16.86 +     * @param      b   the <code>byte</code> to be written.
   16.87 +     * @exception  IOException  if an I/O error occurs.
   16.88 +     * @see        java.io.FilterOutputStream#out
   16.89 +     */
   16.90 +    public synchronized void write(int b) throws IOException {
   16.91 +        out.write(b);
   16.92 +        incCount(1);
   16.93 +    }
   16.94 +
   16.95 +    /**
   16.96 +     * Writes <code>len</code> bytes from the specified byte array
   16.97 +     * starting at offset <code>off</code> to the underlying output stream.
   16.98 +     * If no exception is thrown, the counter <code>written</code> is
   16.99 +     * incremented by <code>len</code>.
  16.100 +     *
  16.101 +     * @param      b     the data.
  16.102 +     * @param      off   the start offset in the data.
  16.103 +     * @param      len   the number of bytes to write.
  16.104 +     * @exception  IOException  if an I/O error occurs.
  16.105 +     * @see        java.io.FilterOutputStream#out
  16.106 +     */
  16.107 +    public synchronized void write(byte b[], int off, int len)
  16.108 +        throws IOException
  16.109 +    {
  16.110 +        out.write(b, off, len);
  16.111 +        incCount(len);
  16.112 +    }
  16.113 +
  16.114 +    /**
  16.115 +     * Flushes this data output stream. This forces any buffered output
  16.116 +     * bytes to be written out to the stream.
  16.117 +     * <p>
  16.118 +     * The <code>flush</code> method of <code>DataOutputStream</code>
  16.119 +     * calls the <code>flush</code> method of its underlying output stream.
  16.120 +     *
  16.121 +     * @exception  IOException  if an I/O error occurs.
  16.122 +     * @see        java.io.FilterOutputStream#out
  16.123 +     * @see        java.io.OutputStream#flush()
  16.124 +     */
  16.125 +    public void flush() throws IOException {
  16.126 +        out.flush();
  16.127 +    }
  16.128 +
  16.129 +    /**
  16.130 +     * Writes a <code>boolean</code> to the underlying output stream as
  16.131 +     * a 1-byte value. The value <code>true</code> is written out as the
  16.132 +     * value <code>(byte)1</code>; the value <code>false</code> is
  16.133 +     * written out as the value <code>(byte)0</code>. If no exception is
  16.134 +     * thrown, the counter <code>written</code> is incremented by
  16.135 +     * <code>1</code>.
  16.136 +     *
  16.137 +     * @param      v   a <code>boolean</code> value to be written.
  16.138 +     * @exception  IOException  if an I/O error occurs.
  16.139 +     * @see        java.io.FilterOutputStream#out
  16.140 +     */
  16.141 +    public final void writeBoolean(boolean v) throws IOException {
  16.142 +        out.write(v ? 1 : 0);
  16.143 +        incCount(1);
  16.144 +    }
  16.145 +
  16.146 +    /**
  16.147 +     * Writes out a <code>byte</code> to the underlying output stream as
  16.148 +     * a 1-byte value. If no exception is thrown, the counter
  16.149 +     * <code>written</code> is incremented by <code>1</code>.
  16.150 +     *
  16.151 +     * @param      v   a <code>byte</code> value to be written.
  16.152 +     * @exception  IOException  if an I/O error occurs.
  16.153 +     * @see        java.io.FilterOutputStream#out
  16.154 +     */
  16.155 +    public final void writeByte(int v) throws IOException {
  16.156 +        out.write(v);
  16.157 +        incCount(1);
  16.158 +    }
  16.159 +
  16.160 +    /**
  16.161 +     * Writes a <code>short</code> to the underlying output stream as two
  16.162 +     * bytes, high byte first. If no exception is thrown, the counter
  16.163 +     * <code>written</code> is incremented by <code>2</code>.
  16.164 +     *
  16.165 +     * @param      v   a <code>short</code> to be written.
  16.166 +     * @exception  IOException  if an I/O error occurs.
  16.167 +     * @see        java.io.FilterOutputStream#out
  16.168 +     */
  16.169 +    public final void writeShort(int v) throws IOException {
  16.170 +        out.write((v >>> 8) & 0xFF);
  16.171 +        out.write((v >>> 0) & 0xFF);
  16.172 +        incCount(2);
  16.173 +    }
  16.174 +
  16.175 +    /**
  16.176 +     * Writes a <code>char</code> to the underlying output stream as a
  16.177 +     * 2-byte value, high byte first. If no exception is thrown, the
  16.178 +     * counter <code>written</code> is incremented by <code>2</code>.
  16.179 +     *
  16.180 +     * @param      v   a <code>char</code> value to be written.
  16.181 +     * @exception  IOException  if an I/O error occurs.
  16.182 +     * @see        java.io.FilterOutputStream#out
  16.183 +     */
  16.184 +    public final void writeChar(int v) throws IOException {
  16.185 +        out.write((v >>> 8) & 0xFF);
  16.186 +        out.write((v >>> 0) & 0xFF);
  16.187 +        incCount(2);
  16.188 +    }
  16.189 +
  16.190 +    /**
  16.191 +     * Writes an <code>int</code> to the underlying output stream as four
  16.192 +     * bytes, high byte first. If no exception is thrown, the counter
  16.193 +     * <code>written</code> is incremented by <code>4</code>.
  16.194 +     *
  16.195 +     * @param      v   an <code>int</code> to be written.
  16.196 +     * @exception  IOException  if an I/O error occurs.
  16.197 +     * @see        java.io.FilterOutputStream#out
  16.198 +     */
  16.199 +    public final void writeInt(int v) throws IOException {
  16.200 +        out.write((v >>> 24) & 0xFF);
  16.201 +        out.write((v >>> 16) & 0xFF);
  16.202 +        out.write((v >>>  8) & 0xFF);
  16.203 +        out.write((v >>>  0) & 0xFF);
  16.204 +        incCount(4);
  16.205 +    }
  16.206 +
  16.207 +    private byte writeBuffer[] = new byte[8];
  16.208 +
  16.209 +    /**
  16.210 +     * Writes a <code>long</code> to the underlying output stream as eight
  16.211 +     * bytes, high byte first. In no exception is thrown, the counter
  16.212 +     * <code>written</code> is incremented by <code>8</code>.
  16.213 +     *
  16.214 +     * @param      v   a <code>long</code> to be written.
  16.215 +     * @exception  IOException  if an I/O error occurs.
  16.216 +     * @see        java.io.FilterOutputStream#out
  16.217 +     */
  16.218 +    public final void writeLong(long v) throws IOException {
  16.219 +        writeBuffer[0] = (byte)(v >>> 56);
  16.220 +        writeBuffer[1] = (byte)(v >>> 48);
  16.221 +        writeBuffer[2] = (byte)(v >>> 40);
  16.222 +        writeBuffer[3] = (byte)(v >>> 32);
  16.223 +        writeBuffer[4] = (byte)(v >>> 24);
  16.224 +        writeBuffer[5] = (byte)(v >>> 16);
  16.225 +        writeBuffer[6] = (byte)(v >>>  8);
  16.226 +        writeBuffer[7] = (byte)(v >>>  0);
  16.227 +        out.write(writeBuffer, 0, 8);
  16.228 +        incCount(8);
  16.229 +    }
  16.230 +
  16.231 +    /**
  16.232 +     * Converts the float argument to an <code>int</code> using the
  16.233 +     * <code>floatToIntBits</code> method in class <code>Float</code>,
  16.234 +     * and then writes that <code>int</code> value to the underlying
  16.235 +     * output stream as a 4-byte quantity, high byte first. If no
  16.236 +     * exception is thrown, the counter <code>written</code> is
  16.237 +     * incremented by <code>4</code>.
  16.238 +     *
  16.239 +     * @param      v   a <code>float</code> value to be written.
  16.240 +     * @exception  IOException  if an I/O error occurs.
  16.241 +     * @see        java.io.FilterOutputStream#out
  16.242 +     * @see        java.lang.Float#floatToIntBits(float)
  16.243 +     */
  16.244 +    public final void writeFloat(float v) throws IOException {
  16.245 +        writeInt(Float.floatToIntBits(v));
  16.246 +    }
  16.247 +
  16.248 +    /**
  16.249 +     * Converts the double argument to a <code>long</code> using the
  16.250 +     * <code>doubleToLongBits</code> method in class <code>Double</code>,
  16.251 +     * and then writes that <code>long</code> value to the underlying
  16.252 +     * output stream as an 8-byte quantity, high byte first. If no
  16.253 +     * exception is thrown, the counter <code>written</code> is
  16.254 +     * incremented by <code>8</code>.
  16.255 +     *
  16.256 +     * @param      v   a <code>double</code> value to be written.
  16.257 +     * @exception  IOException  if an I/O error occurs.
  16.258 +     * @see        java.io.FilterOutputStream#out
  16.259 +     * @see        java.lang.Double#doubleToLongBits(double)
  16.260 +     */
  16.261 +    public final void writeDouble(double v) throws IOException {
  16.262 +        writeLong(Double.doubleToLongBits(v));
  16.263 +    }
  16.264 +
  16.265 +    /**
  16.266 +     * Writes out the string to the underlying output stream as a
  16.267 +     * sequence of bytes. Each character in the string is written out, in
  16.268 +     * sequence, by discarding its high eight bits. If no exception is
  16.269 +     * thrown, the counter <code>written</code> is incremented by the
  16.270 +     * length of <code>s</code>.
  16.271 +     *
  16.272 +     * @param      s   a string of bytes to be written.
  16.273 +     * @exception  IOException  if an I/O error occurs.
  16.274 +     * @see        java.io.FilterOutputStream#out
  16.275 +     */
  16.276 +    public final void writeBytes(String s) throws IOException {
  16.277 +        int len = s.length();
  16.278 +        for (int i = 0 ; i < len ; i++) {
  16.279 +            out.write((byte)s.charAt(i));
  16.280 +        }
  16.281 +        incCount(len);
  16.282 +    }
  16.283 +
  16.284 +    /**
  16.285 +     * Writes a string to the underlying output stream as a sequence of
  16.286 +     * characters. Each character is written to the data output stream as
  16.287 +     * if by the <code>writeChar</code> method. If no exception is
  16.288 +     * thrown, the counter <code>written</code> is incremented by twice
  16.289 +     * the length of <code>s</code>.
  16.290 +     *
  16.291 +     * @param      s   a <code>String</code> value to be written.
  16.292 +     * @exception  IOException  if an I/O error occurs.
  16.293 +     * @see        java.io.DataOutputStream#writeChar(int)
  16.294 +     * @see        java.io.FilterOutputStream#out
  16.295 +     */
  16.296 +    public final void writeChars(String s) throws IOException {
  16.297 +        int len = s.length();
  16.298 +        for (int i = 0 ; i < len ; i++) {
  16.299 +            int v = s.charAt(i);
  16.300 +            out.write((v >>> 8) & 0xFF);
  16.301 +            out.write((v >>> 0) & 0xFF);
  16.302 +        }
  16.303 +        incCount(len * 2);
  16.304 +    }
  16.305 +
  16.306 +    /**
  16.307 +     * Writes a string to the underlying output stream using
  16.308 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  16.309 +     * encoding in a machine-independent manner.
  16.310 +     * <p>
  16.311 +     * First, two bytes are written to the output stream as if by the
  16.312 +     * <code>writeShort</code> method giving the number of bytes to
  16.313 +     * follow. This value is the number of bytes actually written out,
  16.314 +     * not the length of the string. Following the length, each character
  16.315 +     * of the string is output, in sequence, using the modified UTF-8 encoding
  16.316 +     * for the character. If no exception is thrown, the counter
  16.317 +     * <code>written</code> is incremented by the total number of
  16.318 +     * bytes written to the output stream. This will be at least two
  16.319 +     * plus the length of <code>str</code>, and at most two plus
  16.320 +     * thrice the length of <code>str</code>.
  16.321 +     *
  16.322 +     * @param      str   a string to be written.
  16.323 +     * @exception  IOException  if an I/O error occurs.
  16.324 +     */
  16.325 +    public final void writeUTF(String str) throws IOException {
  16.326 +        writeUTF(str, this);
  16.327 +    }
  16.328 +
  16.329 +    /**
  16.330 +     * Writes a string to the specified DataOutput using
  16.331 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  16.332 +     * encoding in a machine-independent manner.
  16.333 +     * <p>
  16.334 +     * First, two bytes are written to out as if by the <code>writeShort</code>
  16.335 +     * method giving the number of bytes to follow. This value is the number of
  16.336 +     * bytes actually written out, not the length of the string. Following the
  16.337 +     * length, each character of the string is output, in sequence, using the
  16.338 +     * modified UTF-8 encoding for the character. If no exception is thrown, the
  16.339 +     * counter <code>written</code> is incremented by the total number of
  16.340 +     * bytes written to the output stream. This will be at least two
  16.341 +     * plus the length of <code>str</code>, and at most two plus
  16.342 +     * thrice the length of <code>str</code>.
  16.343 +     *
  16.344 +     * @param      str   a string to be written.
  16.345 +     * @param      out   destination to write to
  16.346 +     * @return     The number of bytes written out.
  16.347 +     * @exception  IOException  if an I/O error occurs.
  16.348 +     */
  16.349 +    static int writeUTF(String str, DataOutput out) throws IOException {
  16.350 +        int strlen = str.length();
  16.351 +        int utflen = 0;
  16.352 +        int c, count = 0;
  16.353 +
  16.354 +        /* use charAt instead of copying String to char array */
  16.355 +        for (int i = 0; i < strlen; i++) {
  16.356 +            c = str.charAt(i);
  16.357 +            if ((c >= 0x0001) && (c <= 0x007F)) {
  16.358 +                utflen++;
  16.359 +            } else if (c > 0x07FF) {
  16.360 +                utflen += 3;
  16.361 +            } else {
  16.362 +                utflen += 2;
  16.363 +            }
  16.364 +        }
  16.365 +
  16.366 +        if (utflen > 65535)
  16.367 +            throw new UTFDataFormatException(
  16.368 +                "encoded string too long: " + utflen + " bytes");
  16.369 +
  16.370 +        byte[] bytearr = null;
  16.371 +        if (out instanceof DataOutputStream) {
  16.372 +            DataOutputStream dos = (DataOutputStream)out;
  16.373 +            if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
  16.374 +                dos.bytearr = new byte[(utflen*2) + 2];
  16.375 +            bytearr = dos.bytearr;
  16.376 +        } else {
  16.377 +            bytearr = new byte[utflen+2];
  16.378 +        }
  16.379 +
  16.380 +        bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
  16.381 +        bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
  16.382 +
  16.383 +        int i=0;
  16.384 +        for (i=0; i<strlen; i++) {
  16.385 +           c = str.charAt(i);
  16.386 +           if (!((c >= 0x0001) && (c <= 0x007F))) break;
  16.387 +           bytearr[count++] = (byte) c;
  16.388 +        }
  16.389 +
  16.390 +        for (;i < strlen; i++){
  16.391 +            c = str.charAt(i);
  16.392 +            if ((c >= 0x0001) && (c <= 0x007F)) {
  16.393 +                bytearr[count++] = (byte) c;
  16.394 +
  16.395 +            } else if (c > 0x07FF) {
  16.396 +                bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
  16.397 +                bytearr[count++] = (byte) (0x80 | ((c >>  6) & 0x3F));
  16.398 +                bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
  16.399 +            } else {
  16.400 +                bytearr[count++] = (byte) (0xC0 | ((c >>  6) & 0x1F));
  16.401 +                bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
  16.402 +            }
  16.403 +        }
  16.404 +        out.write(bytearr, 0, utflen+2);
  16.405 +        return utflen + 2;
  16.406 +    }
  16.407 +
  16.408 +    /**
  16.409 +     * Returns the current value of the counter <code>written</code>,
  16.410 +     * the number of bytes written to this data output stream so far.
  16.411 +     * If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
  16.412 +     *
  16.413 +     * @return  the value of the <code>written</code> field.
  16.414 +     * @see     java.io.DataOutputStream#written
  16.415 +     */
  16.416 +    public final int size() {
  16.417 +        return written;
  16.418 +    }
  16.419 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/emul/compact/src/main/java/java/io/Externalizable.java	Tue Feb 05 17:04:22 2013 +0100
    17.3 @@ -0,0 +1,97 @@
    17.4 +/*
    17.5 + * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + *
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.  Oracle designates this
   17.11 + * particular file as subject to the "Classpath" exception as provided
   17.12 + * by Oracle in the LICENSE file that accompanied this code.
   17.13 + *
   17.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.17 + * version 2 for more details (a copy is included in the LICENSE file that
   17.18 + * accompanied this code).
   17.19 + *
   17.20 + * You should have received a copy of the GNU General Public License version
   17.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.23 + *
   17.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.25 + * or visit www.oracle.com if you need additional information or have any
   17.26 + * questions.
   17.27 + */
   17.28 +
   17.29 +package java.io;
   17.30 +
   17.31 +import java.io.ObjectOutput;
   17.32 +import java.io.ObjectInput;
   17.33 +
   17.34 +/**
   17.35 + * Only the identity of the class of an Externalizable instance is
   17.36 + * written in the serialization stream and it is the responsibility
   17.37 + * of the class to save and restore the contents of its instances.
   17.38 + *
   17.39 + * The writeExternal and readExternal methods of the Externalizable
   17.40 + * interface are implemented by a class to give the class complete
   17.41 + * control over the format and contents of the stream for an object
   17.42 + * and its supertypes. These methods must explicitly
   17.43 + * coordinate with the supertype to save its state. These methods supersede
   17.44 + * customized implementations of writeObject and readObject methods.<br>
   17.45 + *
   17.46 + * Object Serialization uses the Serializable and Externalizable
   17.47 + * interfaces.  Object persistence mechanisms can use them as well.  Each
   17.48 + * object to be stored is tested for the Externalizable interface. If
   17.49 + * the object supports Externalizable, the writeExternal method is called. If the
   17.50 + * object does not support Externalizable and does implement
   17.51 + * Serializable, the object is saved using
   17.52 + * ObjectOutputStream. <br> When an Externalizable object is
   17.53 + * reconstructed, an instance is created using the public no-arg
   17.54 + * constructor, then the readExternal method called.  Serializable
   17.55 + * objects are restored by reading them from an ObjectInputStream.<br>
   17.56 + *
   17.57 + * An Externalizable instance can designate a substitution object via
   17.58 + * the writeReplace and readResolve methods documented in the Serializable
   17.59 + * interface.<br>
   17.60 + *
   17.61 + * @author  unascribed
   17.62 + * @see java.io.ObjectOutputStream
   17.63 + * @see java.io.ObjectInputStream
   17.64 + * @see java.io.ObjectOutput
   17.65 + * @see java.io.ObjectInput
   17.66 + * @see java.io.Serializable
   17.67 + * @since   JDK1.1
   17.68 + */
   17.69 +public interface Externalizable extends java.io.Serializable {
   17.70 +    /**
   17.71 +     * The object implements the writeExternal method to save its contents
   17.72 +     * by calling the methods of DataOutput for its primitive values or
   17.73 +     * calling the writeObject method of ObjectOutput for objects, strings,
   17.74 +     * and arrays.
   17.75 +     *
   17.76 +     * @serialData Overriding methods should use this tag to describe
   17.77 +     *             the data layout of this Externalizable object.
   17.78 +     *             List the sequence of element types and, if possible,
   17.79 +     *             relate the element to a public/protected field and/or
   17.80 +     *             method of this Externalizable class.
   17.81 +     *
   17.82 +     * @param out the stream to write the object to
   17.83 +     * @exception IOException Includes any I/O exceptions that may occur
   17.84 +     */
   17.85 +    void writeExternal(ObjectOutput out) throws IOException;
   17.86 +
   17.87 +    /**
   17.88 +     * The object implements the readExternal method to restore its
   17.89 +     * contents by calling the methods of DataInput for primitive
   17.90 +     * types and readObject for objects, strings and arrays.  The
   17.91 +     * readExternal method must read the values in the same sequence
   17.92 +     * and with the same types as were written by writeExternal.
   17.93 +     *
   17.94 +     * @param in the stream to read data from in order to restore the object
   17.95 +     * @exception IOException if I/O errors occur
   17.96 +     * @exception ClassNotFoundException If the class for an object being
   17.97 +     *              restored cannot be found.
   17.98 +     */
   17.99 +    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
  17.100 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/emul/compact/src/main/java/java/io/FilterOutputStream.java	Tue Feb 05 17:04:22 2013 +0100
    18.3 @@ -0,0 +1,162 @@
    18.4 +/*
    18.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
    18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.7 + *
    18.8 + * This code is free software; you can redistribute it and/or modify it
    18.9 + * under the terms of the GNU General Public License version 2 only, as
   18.10 + * published by the Free Software Foundation.  Oracle designates this
   18.11 + * particular file as subject to the "Classpath" exception as provided
   18.12 + * by Oracle in the LICENSE file that accompanied this code.
   18.13 + *
   18.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   18.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18.17 + * version 2 for more details (a copy is included in the LICENSE file that
   18.18 + * accompanied this code).
   18.19 + *
   18.20 + * You should have received a copy of the GNU General Public License version
   18.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   18.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18.23 + *
   18.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   18.25 + * or visit www.oracle.com if you need additional information or have any
   18.26 + * questions.
   18.27 + */
   18.28 +
   18.29 +package java.io;
   18.30 +
   18.31 +/**
   18.32 + * This class is the superclass of all classes that filter output
   18.33 + * streams. These streams sit on top of an already existing output
   18.34 + * stream (the <i>underlying</i> output stream) which it uses as its
   18.35 + * basic sink of data, but possibly transforming the data along the
   18.36 + * way or providing additional functionality.
   18.37 + * <p>
   18.38 + * The class <code>FilterOutputStream</code> itself simply overrides
   18.39 + * all methods of <code>OutputStream</code> with versions that pass
   18.40 + * all requests to the underlying output stream. Subclasses of
   18.41 + * <code>FilterOutputStream</code> may further override some of these
   18.42 + * methods as well as provide additional methods and fields.
   18.43 + *
   18.44 + * @author  Jonathan Payne
   18.45 + * @since   JDK1.0
   18.46 + */
   18.47 +public
   18.48 +class FilterOutputStream extends OutputStream {
   18.49 +    /**
   18.50 +     * The underlying output stream to be filtered.
   18.51 +     */
   18.52 +    protected OutputStream out;
   18.53 +
   18.54 +    /**
   18.55 +     * Creates an output stream filter built on top of the specified
   18.56 +     * underlying output stream.
   18.57 +     *
   18.58 +     * @param   out   the underlying output stream to be assigned to
   18.59 +     *                the field <tt>this.out</tt> for later use, or
   18.60 +     *                <code>null</code> if this instance is to be
   18.61 +     *                created without an underlying stream.
   18.62 +     */
   18.63 +    public FilterOutputStream(OutputStream out) {
   18.64 +        this.out = out;
   18.65 +    }
   18.66 +
   18.67 +    /**
   18.68 +     * Writes the specified <code>byte</code> to this output stream.
   18.69 +     * <p>
   18.70 +     * The <code>write</code> method of <code>FilterOutputStream</code>
   18.71 +     * calls the <code>write</code> method of its underlying output stream,
   18.72 +     * that is, it performs <tt>out.write(b)</tt>.
   18.73 +     * <p>
   18.74 +     * Implements the abstract <tt>write</tt> method of <tt>OutputStream</tt>.
   18.75 +     *
   18.76 +     * @param      b   the <code>byte</code>.
   18.77 +     * @exception  IOException  if an I/O error occurs.
   18.78 +     */
   18.79 +    public void write(int b) throws IOException {
   18.80 +        out.write(b);
   18.81 +    }
   18.82 +
   18.83 +    /**
   18.84 +     * Writes <code>b.length</code> bytes to this output stream.
   18.85 +     * <p>
   18.86 +     * The <code>write</code> method of <code>FilterOutputStream</code>
   18.87 +     * calls its <code>write</code> method of three arguments with the
   18.88 +     * arguments <code>b</code>, <code>0</code>, and
   18.89 +     * <code>b.length</code>.
   18.90 +     * <p>
   18.91 +     * Note that this method does not call the one-argument
   18.92 +     * <code>write</code> method of its underlying stream with the single
   18.93 +     * argument <code>b</code>.
   18.94 +     *
   18.95 +     * @param      b   the data to be written.
   18.96 +     * @exception  IOException  if an I/O error occurs.
   18.97 +     * @see        java.io.FilterOutputStream#write(byte[], int, int)
   18.98 +     */
   18.99 +    public void write(byte b[]) throws IOException {
  18.100 +        write(b, 0, b.length);
  18.101 +    }
  18.102 +
  18.103 +    /**
  18.104 +     * Writes <code>len</code> bytes from the specified
  18.105 +     * <code>byte</code> array starting at offset <code>off</code> to
  18.106 +     * this output stream.
  18.107 +     * <p>
  18.108 +     * The <code>write</code> method of <code>FilterOutputStream</code>
  18.109 +     * calls the <code>write</code> method of one argument on each
  18.110 +     * <code>byte</code> to output.
  18.111 +     * <p>
  18.112 +     * Note that this method does not call the <code>write</code> method
  18.113 +     * of its underlying input stream with the same arguments. Subclasses
  18.114 +     * of <code>FilterOutputStream</code> should provide a more efficient
  18.115 +     * implementation of this method.
  18.116 +     *
  18.117 +     * @param      b     the data.
  18.118 +     * @param      off   the start offset in the data.
  18.119 +     * @param      len   the number of bytes to write.
  18.120 +     * @exception  IOException  if an I/O error occurs.
  18.121 +     * @see        java.io.FilterOutputStream#write(int)
  18.122 +     */
  18.123 +    public void write(byte b[], int off, int len) throws IOException {
  18.124 +        if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
  18.125 +            throw new IndexOutOfBoundsException();
  18.126 +
  18.127 +        for (int i = 0 ; i < len ; i++) {
  18.128 +            write(b[off + i]);
  18.129 +        }
  18.130 +    }
  18.131 +
  18.132 +    /**
  18.133 +     * Flushes this output stream and forces any buffered output bytes
  18.134 +     * to be written out to the stream.
  18.135 +     * <p>
  18.136 +     * The <code>flush</code> method of <code>FilterOutputStream</code>
  18.137 +     * calls the <code>flush</code> method of its underlying output stream.
  18.138 +     *
  18.139 +     * @exception  IOException  if an I/O error occurs.
  18.140 +     * @see        java.io.FilterOutputStream#out
  18.141 +     */
  18.142 +    public void flush() throws IOException {
  18.143 +        out.flush();
  18.144 +    }
  18.145 +
  18.146 +    /**
  18.147 +     * Closes this output stream and releases any system resources
  18.148 +     * associated with the stream.
  18.149 +     * <p>
  18.150 +     * The <code>close</code> method of <code>FilterOutputStream</code>
  18.151 +     * calls its <code>flush</code> method, and then calls the
  18.152 +     * <code>close</code> method of its underlying output stream.
  18.153 +     *
  18.154 +     * @exception  IOException  if an I/O error occurs.
  18.155 +     * @see        java.io.FilterOutputStream#flush()
  18.156 +     * @see        java.io.FilterOutputStream#out
  18.157 +     */
  18.158 +    public void close() throws IOException {
  18.159 +        try {
  18.160 +          flush();
  18.161 +        } catch (IOException ignored) {
  18.162 +        }
  18.163 +        out.close();
  18.164 +    }
  18.165 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/emul/compact/src/main/java/java/io/Flushable.java	Tue Feb 05 17:04:22 2013 +0100
    19.3 @@ -0,0 +1,47 @@
    19.4 +/*
    19.5 + * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
    19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    19.7 + *
    19.8 + * This code is free software; you can redistribute it and/or modify it
    19.9 + * under the terms of the GNU General Public License version 2 only, as
   19.10 + * published by the Free Software Foundation.  Oracle designates this
   19.11 + * particular file as subject to the "Classpath" exception as provided
   19.12 + * by Oracle in the LICENSE file that accompanied this code.
   19.13 + *
   19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   19.17 + * version 2 for more details (a copy is included in the LICENSE file that
   19.18 + * accompanied this code).
   19.19 + *
   19.20 + * You should have received a copy of the GNU General Public License version
   19.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   19.23 + *
   19.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   19.25 + * or visit www.oracle.com if you need additional information or have any
   19.26 + * questions.
   19.27 + */
   19.28 +
   19.29 +package java.io;
   19.30 +
   19.31 +import java.io.IOException;
   19.32 +
   19.33 +/**
   19.34 + * A <tt>Flushable</tt> is a destination of data that can be flushed.  The
   19.35 + * flush method is invoked to write any buffered output to the underlying
   19.36 + * stream.
   19.37 + *
   19.38 + * @since 1.5
   19.39 + */
   19.40 +
   19.41 +public interface Flushable {
   19.42 +
   19.43 +    /**
   19.44 +     * Flushes this stream by writing any buffered output to the underlying
   19.45 +     * stream.
   19.46 +     *
   19.47 +     * @throws IOException If an I/O error occurs
   19.48 +     */
   19.49 +    void flush() throws IOException;
   19.50 +}
    20.1 --- a/emul/compact/src/main/java/java/io/InputStreamReader.java	Tue Feb 05 16:40:01 2013 +0100
    20.2 +++ b/emul/compact/src/main/java/java/io/InputStreamReader.java	Tue Feb 05 17:04:22 2013 +0100
    20.3 @@ -156,9 +156,39 @@
    20.4       * @exception  IOException  If an I/O error occurs
    20.5       */
    20.6      public int read() throws IOException {
    20.7 -        return ((InputStream)lock).read();
    20.8 +        final InputStream is = (InputStream)lock;
    20.9 +        int c = is.read();
   20.10 +        if (c == -1) {
   20.11 +            return -1;
   20.12 +        }
   20.13 +        c = (int) c & 0xff;
   20.14 +        switch (c >> 4) {
   20.15 +            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
   20.16 +                /* 0xxxxxxx*/
   20.17 +                return c;
   20.18 +            case 12: case 13: {
   20.19 +                /* 110x xxxx   10xx xxxx*/
   20.20 +                int char2 = (int) is.read();
   20.21 +                if ((char2 & 0xC0) != 0x80)
   20.22 +                    throw new UTFDataFormatException("malformed input");
   20.23 +                return (((c & 0x1F) << 6) | (char2 & 0x3F));
   20.24 +            }
   20.25 +            case 14: {
   20.26 +                /* 1110 xxxx  10xx xxxx  10xx xxxx */
   20.27 +                int char2 = is.read();
   20.28 +                int char3 = is.read();
   20.29 +                if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
   20.30 +                    throw new UTFDataFormatException("malformed input");
   20.31 +                return (((c    & 0x0F) << 12) |
   20.32 +                       ((char2 & 0x3F) << 6)  |
   20.33 +                       ((char3 & 0x3F) << 0));
   20.34 +            }
   20.35 +            default:
   20.36 +                /* 10xx xxxx,  1111 xxxx */
   20.37 +                throw new UTFDataFormatException("malformed input");
   20.38 +        }
   20.39      }
   20.40 -
   20.41 +    
   20.42      /**
   20.43       * Reads characters into a portion of an array.
   20.44       *
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/emul/compact/src/main/java/java/io/InvalidClassException.java	Tue Feb 05 17:04:22 2013 +0100
    21.3 @@ -0,0 +1,81 @@
    21.4 +/*
    21.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.7 + *
    21.8 + * This code is free software; you can redistribute it and/or modify it
    21.9 + * under the terms of the GNU General Public License version 2 only, as
   21.10 + * published by the Free Software Foundation.  Oracle designates this
   21.11 + * particular file as subject to the "Classpath" exception as provided
   21.12 + * by Oracle in the LICENSE file that accompanied this code.
   21.13 + *
   21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   21.17 + * version 2 for more details (a copy is included in the LICENSE file that
   21.18 + * accompanied this code).
   21.19 + *
   21.20 + * You should have received a copy of the GNU General Public License version
   21.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   21.23 + *
   21.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   21.25 + * or visit www.oracle.com if you need additional information or have any
   21.26 + * questions.
   21.27 + */
   21.28 +
   21.29 +package java.io;
   21.30 +
   21.31 +/**
   21.32 + * Thrown when the Serialization runtime detects one of the following
   21.33 + * problems with a Class.
   21.34 + * <UL>
   21.35 + * <LI> The serial version of the class does not match that of the class
   21.36 + *      descriptor read from the stream
   21.37 + * <LI> The class contains unknown datatypes
   21.38 + * <LI> The class does not have an accessible no-arg constructor
   21.39 + * </UL>
   21.40 + *
   21.41 + * @author  unascribed
   21.42 + * @since   JDK1.1
   21.43 + */
   21.44 +public class InvalidClassException extends ObjectStreamException {
   21.45 +
   21.46 +    private static final long serialVersionUID = -4333316296251054416L;
   21.47 +
   21.48 +    /**
   21.49 +     * Name of the invalid class.
   21.50 +     *
   21.51 +     * @serial Name of the invalid class.
   21.52 +     */
   21.53 +    public String classname;
   21.54 +
   21.55 +    /**
   21.56 +     * Report an InvalidClassException for the reason specified.
   21.57 +     *
   21.58 +     * @param reason  String describing the reason for the exception.
   21.59 +     */
   21.60 +    public InvalidClassException(String reason) {
   21.61 +        super(reason);
   21.62 +    }
   21.63 +
   21.64 +    /**
   21.65 +     * Constructs an InvalidClassException object.
   21.66 +     *
   21.67 +     * @param cname   a String naming the invalid class.
   21.68 +     * @param reason  a String describing the reason for the exception.
   21.69 +     */
   21.70 +    public InvalidClassException(String cname, String reason) {
   21.71 +        super(reason);
   21.72 +        classname = cname;
   21.73 +    }
   21.74 +
   21.75 +    /**
   21.76 +     * Produce the message and include the classname, if present.
   21.77 +     */
   21.78 +    public String getMessage() {
   21.79 +        if (classname == null)
   21.80 +            return super.getMessage();
   21.81 +        else
   21.82 +            return classname + "; " + super.getMessage();
   21.83 +    }
   21.84 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/emul/compact/src/main/java/java/io/InvalidObjectException.java	Tue Feb 05 17:04:22 2013 +0100
    22.3 @@ -0,0 +1,51 @@
    22.4 +/*
    22.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.7 + *
    22.8 + * This code is free software; you can redistribute it and/or modify it
    22.9 + * under the terms of the GNU General Public License version 2 only, as
   22.10 + * published by the Free Software Foundation.  Oracle designates this
   22.11 + * particular file as subject to the "Classpath" exception as provided
   22.12 + * by Oracle in the LICENSE file that accompanied this code.
   22.13 + *
   22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.17 + * version 2 for more details (a copy is included in the LICENSE file that
   22.18 + * accompanied this code).
   22.19 + *
   22.20 + * You should have received a copy of the GNU General Public License version
   22.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.23 + *
   22.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22.25 + * or visit www.oracle.com if you need additional information or have any
   22.26 + * questions.
   22.27 + */
   22.28 +
   22.29 +package java.io;
   22.30 +
   22.31 +/**
   22.32 + * Indicates that one or more deserialized objects failed validation
   22.33 + * tests.  The argument should provide the reason for the failure.
   22.34 + *
   22.35 + * @see ObjectInputValidation
   22.36 + * @since JDK1.1
   22.37 + *
   22.38 + * @author  unascribed
   22.39 + * @since   JDK1.1
   22.40 + */
   22.41 +public class InvalidObjectException extends ObjectStreamException {
   22.42 +
   22.43 +    private static final long serialVersionUID = 3233174318281839583L;
   22.44 +
   22.45 +    /**
   22.46 +     * Constructs an <code>InvalidObjectException</code>.
   22.47 +     * @param reason Detailed message explaining the reason for the failure.
   22.48 +     *
   22.49 +     * @see ObjectInputValidation
   22.50 +     */
   22.51 +    public  InvalidObjectException(String reason) {
   22.52 +        super(reason);
   22.53 +    }
   22.54 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/emul/compact/src/main/java/java/io/NotActiveException.java	Tue Feb 05 17:04:22 2013 +0100
    23.3 @@ -0,0 +1,53 @@
    23.4 +/*
    23.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.7 + *
    23.8 + * This code is free software; you can redistribute it and/or modify it
    23.9 + * under the terms of the GNU General Public License version 2 only, as
   23.10 + * published by the Free Software Foundation.  Oracle designates this
   23.11 + * particular file as subject to the "Classpath" exception as provided
   23.12 + * by Oracle in the LICENSE file that accompanied this code.
   23.13 + *
   23.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   23.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   23.17 + * version 2 for more details (a copy is included in the LICENSE file that
   23.18 + * accompanied this code).
   23.19 + *
   23.20 + * You should have received a copy of the GNU General Public License version
   23.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   23.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   23.23 + *
   23.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   23.25 + * or visit www.oracle.com if you need additional information or have any
   23.26 + * questions.
   23.27 + */
   23.28 +
   23.29 +package java.io;
   23.30 +
   23.31 +/**
   23.32 + * Thrown when serialization or deserialization is not active.
   23.33 + *
   23.34 + * @author  unascribed
   23.35 + * @since   JDK1.1
   23.36 + */
   23.37 +public class NotActiveException extends ObjectStreamException {
   23.38 +
   23.39 +    private static final long serialVersionUID = -3893467273049808895L;
   23.40 +
   23.41 +    /**
   23.42 +     * Constructor to create a new NotActiveException with the reason given.
   23.43 +     *
   23.44 +     * @param reason  a String describing the reason for the exception.
   23.45 +     */
   23.46 +    public NotActiveException(String reason) {
   23.47 +        super(reason);
   23.48 +    }
   23.49 +
   23.50 +    /**
   23.51 +     * Constructor to create a new NotActiveException without a reason.
   23.52 +     */
   23.53 +    public NotActiveException() {
   23.54 +        super();
   23.55 +    }
   23.56 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/emul/compact/src/main/java/java/io/NotSerializableException.java	Tue Feb 05 17:04:22 2013 +0100
    24.3 @@ -0,0 +1,55 @@
    24.4 +/*
    24.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.7 + *
    24.8 + * This code is free software; you can redistribute it and/or modify it
    24.9 + * under the terms of the GNU General Public License version 2 only, as
   24.10 + * published by the Free Software Foundation.  Oracle designates this
   24.11 + * particular file as subject to the "Classpath" exception as provided
   24.12 + * by Oracle in the LICENSE file that accompanied this code.
   24.13 + *
   24.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   24.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   24.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   24.17 + * version 2 for more details (a copy is included in the LICENSE file that
   24.18 + * accompanied this code).
   24.19 + *
   24.20 + * You should have received a copy of the GNU General Public License version
   24.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   24.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24.23 + *
   24.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   24.25 + * or visit www.oracle.com if you need additional information or have any
   24.26 + * questions.
   24.27 + */
   24.28 +
   24.29 +package java.io;
   24.30 +
   24.31 +/**
   24.32 + * Thrown when an instance is required to have a Serializable interface.
   24.33 + * The serialization runtime or the class of the instance can throw
   24.34 + * this exception. The argument should be the name of the class.
   24.35 + *
   24.36 + * @author  unascribed
   24.37 + * @since   JDK1.1
   24.38 + */
   24.39 +public class NotSerializableException extends ObjectStreamException {
   24.40 +
   24.41 +    private static final long serialVersionUID = 2906642554793891381L;
   24.42 +
   24.43 +    /**
   24.44 +     * Constructs a NotSerializableException object with message string.
   24.45 +     *
   24.46 +     * @param classname Class of the instance being serialized/deserialized.
   24.47 +     */
   24.48 +    public NotSerializableException(String classname) {
   24.49 +        super(classname);
   24.50 +    }
   24.51 +
   24.52 +    /**
   24.53 +     *  Constructs a NotSerializableException object.
   24.54 +     */
   24.55 +    public NotSerializableException() {
   24.56 +        super();
   24.57 +    }
   24.58 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/emul/compact/src/main/java/java/io/ObjectInput.java	Tue Feb 05 17:04:22 2013 +0100
    25.3 @@ -0,0 +1,107 @@
    25.4 +/*
    25.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 + *
    25.8 + * This code is free software; you can redistribute it and/or modify it
    25.9 + * under the terms of the GNU General Public License version 2 only, as
   25.10 + * published by the Free Software Foundation.  Oracle designates this
   25.11 + * particular file as subject to the "Classpath" exception as provided
   25.12 + * by Oracle in the LICENSE file that accompanied this code.
   25.13 + *
   25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.17 + * version 2 for more details (a copy is included in the LICENSE file that
   25.18 + * accompanied this code).
   25.19 + *
   25.20 + * You should have received a copy of the GNU General Public License version
   25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.23 + *
   25.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   25.25 + * or visit www.oracle.com if you need additional information or have any
   25.26 + * questions.
   25.27 + */
   25.28 +
   25.29 +package java.io;
   25.30 +
   25.31 +/**
   25.32 + * ObjectInput extends the DataInput interface to include the reading of
   25.33 + * objects. DataInput includes methods for the input of primitive types,
   25.34 + * ObjectInput extends that interface to include objects, arrays, and Strings.
   25.35 + *
   25.36 + * @author  unascribed
   25.37 + * @see java.io.InputStream
   25.38 + * @see java.io.ObjectOutputStream
   25.39 + * @see java.io.ObjectInputStream
   25.40 + * @since   JDK1.1
   25.41 + */
   25.42 +public interface ObjectInput extends DataInput, AutoCloseable {
   25.43 +    /**
   25.44 +     * Read and return an object. The class that implements this interface
   25.45 +     * defines where the object is "read" from.
   25.46 +     *
   25.47 +     * @return the object read from the stream
   25.48 +     * @exception java.lang.ClassNotFoundException If the class of a serialized
   25.49 +     *      object cannot be found.
   25.50 +     * @exception IOException If any of the usual Input/Output
   25.51 +     * related exceptions occur.
   25.52 +     */
   25.53 +    public Object readObject()
   25.54 +        throws ClassNotFoundException, IOException;
   25.55 +
   25.56 +    /**
   25.57 +     * Reads a byte of data. This method will block if no input is
   25.58 +     * available.
   25.59 +     * @return  the byte read, or -1 if the end of the
   25.60 +     *          stream is reached.
   25.61 +     * @exception IOException If an I/O error has occurred.
   25.62 +     */
   25.63 +    public int read() throws IOException;
   25.64 +
   25.65 +    /**
   25.66 +     * Reads into an array of bytes.  This method will
   25.67 +     * block until some input is available.
   25.68 +     * @param b the buffer into which the data is read
   25.69 +     * @return  the actual number of bytes read, -1 is
   25.70 +     *          returned when the end of the stream is reached.
   25.71 +     * @exception IOException If an I/O error has occurred.
   25.72 +     */
   25.73 +    public int read(byte b[]) throws IOException;
   25.74 +
   25.75 +    /**
   25.76 +     * Reads into an array of bytes.  This method will
   25.77 +     * block until some input is available.
   25.78 +     * @param b the buffer into which the data is read
   25.79 +     * @param off the start offset of the data
   25.80 +     * @param len the maximum number of bytes read
   25.81 +     * @return  the actual number of bytes read, -1 is
   25.82 +     *          returned when the end of the stream is reached.
   25.83 +     * @exception IOException If an I/O error has occurred.
   25.84 +     */
   25.85 +    public int read(byte b[], int off, int len) throws IOException;
   25.86 +
   25.87 +    /**
   25.88 +     * Skips n bytes of input.
   25.89 +     * @param n the number of bytes to be skipped
   25.90 +     * @return  the actual number of bytes skipped.
   25.91 +     * @exception IOException If an I/O error has occurred.
   25.92 +     */
   25.93 +    public long skip(long n) throws IOException;
   25.94 +
   25.95 +    /**
   25.96 +     * Returns the number of bytes that can be read
   25.97 +     * without blocking.
   25.98 +     * @return the number of available bytes.
   25.99 +     * @exception IOException If an I/O error has occurred.
  25.100 +     */
  25.101 +    public int available() throws IOException;
  25.102 +
  25.103 +    /**
  25.104 +     * Closes the input stream. Must be called
  25.105 +     * to release any resources associated with
  25.106 +     * the stream.
  25.107 +     * @exception IOException If an I/O error has occurred.
  25.108 +     */
  25.109 +    public void close() throws IOException;
  25.110 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/emul/compact/src/main/java/java/io/ObjectInputStream.java	Tue Feb 05 17:04:22 2013 +0100
    26.3 @@ -0,0 +1,3357 @@
    26.4 +/*
    26.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.7 + *
    26.8 + * This code is free software; you can redistribute it and/or modify it
    26.9 + * under the terms of the GNU General Public License version 2 only, as
   26.10 + * published by the Free Software Foundation.  Oracle designates this
   26.11 + * particular file as subject to the "Classpath" exception as provided
   26.12 + * by Oracle in the LICENSE file that accompanied this code.
   26.13 + *
   26.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   26.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   26.17 + * version 2 for more details (a copy is included in the LICENSE file that
   26.18 + * accompanied this code).
   26.19 + *
   26.20 + * You should have received a copy of the GNU General Public License version
   26.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   26.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   26.23 + *
   26.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   26.25 + * or visit www.oracle.com if you need additional information or have any
   26.26 + * questions.
   26.27 + */
   26.28 +
   26.29 +package java.io;
   26.30 +
   26.31 +import java.lang.reflect.Array;
   26.32 +import java.lang.reflect.Modifier;
   26.33 +import java.lang.reflect.Proxy;
   26.34 +import java.util.Arrays;
   26.35 +import java.util.HashMap;
   26.36 +import org.apidesign.bck2brwsr.emul.lang.System;
   26.37 +
   26.38 +/**
   26.39 + * An ObjectInputStream deserializes primitive data and objects previously
   26.40 + * written using an ObjectOutputStream.
   26.41 + *
   26.42 + * <p>ObjectOutputStream and ObjectInputStream can provide an application with
   26.43 + * persistent storage for graphs of objects when used with a FileOutputStream
   26.44 + * and FileInputStream respectively.  ObjectInputStream is used to recover
   26.45 + * those objects previously serialized. Other uses include passing objects
   26.46 + * between hosts using a socket stream or for marshaling and unmarshaling
   26.47 + * arguments and parameters in a remote communication system.
   26.48 + *
   26.49 + * <p>ObjectInputStream ensures that the types of all objects in the graph
   26.50 + * created from the stream match the classes present in the Java Virtual
   26.51 + * Machine.  Classes are loaded as required using the standard mechanisms.
   26.52 + *
   26.53 + * <p>Only objects that support the java.io.Serializable or
   26.54 + * java.io.Externalizable interface can be read from streams.
   26.55 + *
   26.56 + * <p>The method <code>readObject</code> is used to read an object from the
   26.57 + * stream.  Java's safe casting should be used to get the desired type.  In
   26.58 + * Java, strings and arrays are objects and are treated as objects during
   26.59 + * serialization. When read they need to be cast to the expected type.
   26.60 + *
   26.61 + * <p>Primitive data types can be read from the stream using the appropriate
   26.62 + * method on DataInput.
   26.63 + *
   26.64 + * <p>The default deserialization mechanism for objects restores the contents
   26.65 + * of each field to the value and type it had when it was written.  Fields
   26.66 + * declared as transient or static are ignored by the deserialization process.
   26.67 + * References to other objects cause those objects to be read from the stream
   26.68 + * as necessary.  Graphs of objects are restored correctly using a reference
   26.69 + * sharing mechanism.  New objects are always allocated when deserializing,
   26.70 + * which prevents existing objects from being overwritten.
   26.71 + *
   26.72 + * <p>Reading an object is analogous to running the constructors of a new
   26.73 + * object.  Memory is allocated for the object and initialized to zero (NULL).
   26.74 + * No-arg constructors are invoked for the non-serializable classes and then
   26.75 + * the fields of the serializable classes are restored from the stream starting
   26.76 + * with the serializable class closest to java.lang.object and finishing with
   26.77 + * the object's most specific class.
   26.78 + *
   26.79 + * <p>For example to read from a stream as written by the example in
   26.80 + * ObjectOutputStream:
   26.81 + * <br>
   26.82 + * <pre>
   26.83 + *      FileInputStream fis = new FileInputStream("t.tmp");
   26.84 + *      ObjectInputStream ois = new ObjectInputStream(fis);
   26.85 + *
   26.86 + *      int i = ois.readInt();
   26.87 + *      String today = (String) ois.readObject();
   26.88 + *      Date date = (Date) ois.readObject();
   26.89 + *
   26.90 + *      ois.close();
   26.91 + * </pre>
   26.92 + *
   26.93 + * <p>Classes control how they are serialized by implementing either the
   26.94 + * java.io.Serializable or java.io.Externalizable interfaces.
   26.95 + *
   26.96 + * <p>Implementing the Serializable interface allows object serialization to
   26.97 + * save and restore the entire state of the object and it allows classes to
   26.98 + * evolve between the time the stream is written and the time it is read.  It
   26.99 + * automatically traverses references between objects, saving and restoring
  26.100 + * entire graphs.
  26.101 + *
  26.102 + * <p>Serializable classes that require special handling during the
  26.103 + * serialization and deserialization process should implement the following
  26.104 + * methods:<p>
  26.105 + *
  26.106 + * <pre>
  26.107 + * private void writeObject(java.io.ObjectOutputStream stream)
  26.108 + *     throws IOException;
  26.109 + * private void readObject(java.io.ObjectInputStream stream)
  26.110 + *     throws IOException, ClassNotFoundException;
  26.111 + * private void readObjectNoData()
  26.112 + *     throws ObjectStreamException;
  26.113 + * </pre>
  26.114 + *
  26.115 + * <p>The readObject method is responsible for reading and restoring the state
  26.116 + * of the object for its particular class using data written to the stream by
  26.117 + * the corresponding writeObject method.  The method does not need to concern
  26.118 + * itself with the state belonging to its superclasses or subclasses.  State is
  26.119 + * restored by reading data from the ObjectInputStream for the individual
  26.120 + * fields and making assignments to the appropriate fields of the object.
  26.121 + * Reading primitive data types is supported by DataInput.
  26.122 + *
  26.123 + * <p>Any attempt to read object data which exceeds the boundaries of the
  26.124 + * custom data written by the corresponding writeObject method will cause an
  26.125 + * OptionalDataException to be thrown with an eof field value of true.
  26.126 + * Non-object reads which exceed the end of the allotted data will reflect the
  26.127 + * end of data in the same way that they would indicate the end of the stream:
  26.128 + * bytewise reads will return -1 as the byte read or number of bytes read, and
  26.129 + * primitive reads will throw EOFExceptions.  If there is no corresponding
  26.130 + * writeObject method, then the end of default serialized data marks the end of
  26.131 + * the allotted data.
  26.132 + *
  26.133 + * <p>Primitive and object read calls issued from within a readExternal method
  26.134 + * behave in the same manner--if the stream is already positioned at the end of
  26.135 + * data written by the corresponding writeExternal method, object reads will
  26.136 + * throw OptionalDataExceptions with eof set to true, bytewise reads will
  26.137 + * return -1, and primitive reads will throw EOFExceptions.  Note that this
  26.138 + * behavior does not hold for streams written with the old
  26.139 + * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the
  26.140 + * end of data written by writeExternal methods is not demarcated, and hence
  26.141 + * cannot be detected.
  26.142 + *
  26.143 + * <p>The readObjectNoData method is responsible for initializing the state of
  26.144 + * the object for its particular class in the event that the serialization
  26.145 + * stream does not list the given class as a superclass of the object being
  26.146 + * deserialized.  This may occur in cases where the receiving party uses a
  26.147 + * different version of the deserialized instance's class than the sending
  26.148 + * party, and the receiver's version extends classes that are not extended by
  26.149 + * the sender's version.  This may also occur if the serialization stream has
  26.150 + * been tampered; hence, readObjectNoData is useful for initializing
  26.151 + * deserialized objects properly despite a "hostile" or incomplete source
  26.152 + * stream.
  26.153 + *
  26.154 + * <p>Serialization does not read or assign values to the fields of any object
  26.155 + * that does not implement the java.io.Serializable interface.  Subclasses of
  26.156 + * Objects that are not serializable can be serializable. In this case the
  26.157 + * non-serializable class must have a no-arg constructor to allow its fields to
  26.158 + * be initialized.  In this case it is the responsibility of the subclass to
  26.159 + * save and restore the state of the non-serializable class. It is frequently
  26.160 + * the case that the fields of that class are accessible (public, package, or
  26.161 + * protected) or that there are get and set methods that can be used to restore
  26.162 + * the state.
  26.163 + *
  26.164 + * <p>Any exception that occurs while deserializing an object will be caught by
  26.165 + * the ObjectInputStream and abort the reading process.
  26.166 + *
  26.167 + * <p>Implementing the Externalizable interface allows the object to assume
  26.168 + * complete control over the contents and format of the object's serialized
  26.169 + * form.  The methods of the Externalizable interface, writeExternal and
  26.170 + * readExternal, are called to save and restore the objects state.  When
  26.171 + * implemented by a class they can write and read their own state using all of
  26.172 + * the methods of ObjectOutput and ObjectInput.  It is the responsibility of
  26.173 + * the objects to handle any versioning that occurs.
  26.174 + *
  26.175 + * <p>Enum constants are deserialized differently than ordinary serializable or
  26.176 + * externalizable objects.  The serialized form of an enum constant consists
  26.177 + * solely of its name; field values of the constant are not transmitted.  To
  26.178 + * deserialize an enum constant, ObjectInputStream reads the constant name from
  26.179 + * the stream; the deserialized constant is then obtained by calling the static
  26.180 + * method <code>Enum.valueOf(Class, String)</code> with the enum constant's
  26.181 + * base type and the received constant name as arguments.  Like other
  26.182 + * serializable or externalizable objects, enum constants can function as the
  26.183 + * targets of back references appearing subsequently in the serialization
  26.184 + * stream.  The process by which enum constants are deserialized cannot be
  26.185 + * customized: any class-specific readObject, readObjectNoData, and readResolve
  26.186 + * methods defined by enum types are ignored during deserialization.
  26.187 + * Similarly, any serialPersistentFields or serialVersionUID field declarations
  26.188 + * are also ignored--all enum types have a fixed serialVersionUID of 0L.
  26.189 + *
  26.190 + * @author      Mike Warres
  26.191 + * @author      Roger Riggs
  26.192 + * @see java.io.DataInput
  26.193 + * @see java.io.ObjectOutputStream
  26.194 + * @see java.io.Serializable
  26.195 + * @see <a href="../../../platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
  26.196 + * @since   JDK1.1
  26.197 + */
  26.198 +public class ObjectInputStream
  26.199 +    extends InputStream implements ObjectInput, ObjectStreamConstants
  26.200 +{
  26.201 +    /** handle value representing null */
  26.202 +    private static final int NULL_HANDLE = -1;
  26.203 +
  26.204 +    /** marker for unshared objects in internal handle table */
  26.205 +    private static final Object unsharedMarker = new Object();
  26.206 +
  26.207 +    /** table mapping primitive type names to corresponding class objects */
  26.208 +    private static final HashMap<String, Class<?>> primClasses
  26.209 +        = new HashMap<>(8, 1.0F);
  26.210 +    static {
  26.211 +        primClasses.put("boolean", boolean.class);
  26.212 +        primClasses.put("byte", byte.class);
  26.213 +        primClasses.put("char", char.class);
  26.214 +        primClasses.put("short", short.class);
  26.215 +        primClasses.put("int", int.class);
  26.216 +        primClasses.put("long", long.class);
  26.217 +        primClasses.put("float", float.class);
  26.218 +        primClasses.put("double", double.class);
  26.219 +        primClasses.put("void", void.class);
  26.220 +    }
  26.221 +
  26.222 +    /** filter stream for handling block data conversion */
  26.223 +    private final BlockDataInputStream bin;
  26.224 +    /** validation callback list */
  26.225 +    private final ValidationList vlist;
  26.226 +    /** recursion depth */
  26.227 +    private int depth;
  26.228 +    /** whether stream is closed */
  26.229 +    private boolean closed;
  26.230 +
  26.231 +    /** wire handle -> obj/exception map */
  26.232 +    private final HandleTable handles;
  26.233 +    /** scratch field for passing handle values up/down call stack */
  26.234 +    private int passHandle = NULL_HANDLE;
  26.235 +    /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
  26.236 +    private boolean defaultDataEnd = false;
  26.237 +
  26.238 +    /** buffer for reading primitive field values */
  26.239 +    private byte[] primVals;
  26.240 +
  26.241 +    /** if true, invoke readObjectOverride() instead of readObject() */
  26.242 +    private final boolean enableOverride;
  26.243 +    /** if true, invoke resolveObject() */
  26.244 +    private boolean enableResolve;
  26.245 +
  26.246 +    /**
  26.247 +     * Context during upcalls to class-defined readObject methods; holds
  26.248 +     * object currently being deserialized and descriptor for current class.
  26.249 +     * Null when not during readObject upcall.
  26.250 +     */
  26.251 +    private Object curContext;
  26.252 +
  26.253 +    /**
  26.254 +     * Creates an ObjectInputStream that reads from the specified InputStream.
  26.255 +     * A serialization stream header is read from the stream and verified.
  26.256 +     * This constructor will block until the corresponding ObjectOutputStream
  26.257 +     * has written and flushed the header.
  26.258 +     *
  26.259 +     * <p>If a security manager is installed, this constructor will check for
  26.260 +     * the "enableSubclassImplementation" SerializablePermission when invoked
  26.261 +     * directly or indirectly by the constructor of a subclass which overrides
  26.262 +     * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
  26.263 +     * methods.
  26.264 +     *
  26.265 +     * @param   in input stream to read from
  26.266 +     * @throws  StreamCorruptedException if the stream header is incorrect
  26.267 +     * @throws  IOException if an I/O error occurs while reading stream header
  26.268 +     * @throws  SecurityException if untrusted subclass illegally overrides
  26.269 +     *          security-sensitive methods
  26.270 +     * @throws  NullPointerException if <code>in</code> is <code>null</code>
  26.271 +     * @see     ObjectInputStream#ObjectInputStream()
  26.272 +     * @see     ObjectInputStream#readFields()
  26.273 +     * @see     ObjectOutputStream#ObjectOutputStream(OutputStream)
  26.274 +     */
  26.275 +    public ObjectInputStream(InputStream in) throws IOException {
  26.276 +        verifySubclass();
  26.277 +        bin = new BlockDataInputStream(in);
  26.278 +        handles = new HandleTable(10);
  26.279 +        vlist = new ValidationList();
  26.280 +        enableOverride = false;
  26.281 +        readStreamHeader();
  26.282 +        bin.setBlockDataMode(true);
  26.283 +    }
  26.284 +
  26.285 +    /**
  26.286 +     * Provide a way for subclasses that are completely reimplementing
  26.287 +     * ObjectInputStream to not have to allocate private data just used by this
  26.288 +     * implementation of ObjectInputStream.
  26.289 +     *
  26.290 +     * <p>If there is a security manager installed, this method first calls the
  26.291 +     * security manager's <code>checkPermission</code> method with the
  26.292 +     * <code>SerializablePermission("enableSubclassImplementation")</code>
  26.293 +     * permission to ensure it's ok to enable subclassing.
  26.294 +     *
  26.295 +     * @throws  SecurityException if a security manager exists and its
  26.296 +     *          <code>checkPermission</code> method denies enabling
  26.297 +     *          subclassing.
  26.298 +     * @see SecurityManager#checkPermission
  26.299 +     * @see java.io.SerializablePermission
  26.300 +     */
  26.301 +    protected ObjectInputStream() throws IOException, SecurityException {
  26.302 +        throw new SecurityException();
  26.303 +    }
  26.304 +
  26.305 +    /**
  26.306 +     * Read an object from the ObjectInputStream.  The class of the object, the
  26.307 +     * signature of the class, and the values of the non-transient and
  26.308 +     * non-static fields of the class and all of its supertypes are read.
  26.309 +     * Default deserializing for a class can be overriden using the writeObject
  26.310 +     * and readObject methods.  Objects referenced by this object are read
  26.311 +     * transitively so that a complete equivalent graph of objects is
  26.312 +     * reconstructed by readObject.
  26.313 +     *
  26.314 +     * <p>The root object is completely restored when all of its fields and the
  26.315 +     * objects it references are completely restored.  At this point the object
  26.316 +     * validation callbacks are executed in order based on their registered
  26.317 +     * priorities. The callbacks are registered by objects (in the readObject
  26.318 +     * special methods) as they are individually restored.
  26.319 +     *
  26.320 +     * <p>Exceptions are thrown for problems with the InputStream and for
  26.321 +     * classes that should not be deserialized.  All exceptions are fatal to
  26.322 +     * the InputStream and leave it in an indeterminate state; it is up to the
  26.323 +     * caller to ignore or recover the stream state.
  26.324 +     *
  26.325 +     * @throws  ClassNotFoundException Class of a serialized object cannot be
  26.326 +     *          found.
  26.327 +     * @throws  InvalidClassException Something is wrong with a class used by
  26.328 +     *          serialization.
  26.329 +     * @throws  StreamCorruptedException Control information in the
  26.330 +     *          stream is inconsistent.
  26.331 +     * @throws  OptionalDataException Primitive data was found in the
  26.332 +     *          stream instead of objects.
  26.333 +     * @throws  IOException Any of the usual Input/Output related exceptions.
  26.334 +     */
  26.335 +    public final Object readObject()
  26.336 +        throws IOException, ClassNotFoundException
  26.337 +    {
  26.338 +        throw new IOException();
  26.339 +    }
  26.340 +
  26.341 +    /**
  26.342 +     * This method is called by trusted subclasses of ObjectOutputStream that
  26.343 +     * constructed ObjectOutputStream using the protected no-arg constructor.
  26.344 +     * The subclass is expected to provide an override method with the modifier
  26.345 +     * "final".
  26.346 +     *
  26.347 +     * @return  the Object read from the stream.
  26.348 +     * @throws  ClassNotFoundException Class definition of a serialized object
  26.349 +     *          cannot be found.
  26.350 +     * @throws  OptionalDataException Primitive data was found in the stream
  26.351 +     *          instead of objects.
  26.352 +     * @throws  IOException if I/O errors occurred while reading from the
  26.353 +     *          underlying stream
  26.354 +     * @see #ObjectInputStream()
  26.355 +     * @see #readObject()
  26.356 +     * @since 1.2
  26.357 +     */
  26.358 +    protected Object readObjectOverride()
  26.359 +        throws IOException, ClassNotFoundException
  26.360 +    {
  26.361 +        return null;
  26.362 +    }
  26.363 +
  26.364 +    /**
  26.365 +     * Reads an "unshared" object from the ObjectInputStream.  This method is
  26.366 +     * identical to readObject, except that it prevents subsequent calls to
  26.367 +     * readObject and readUnshared from returning additional references to the
  26.368 +     * deserialized instance obtained via this call.  Specifically:
  26.369 +     * <ul>
  26.370 +     *   <li>If readUnshared is called to deserialize a back-reference (the
  26.371 +     *       stream representation of an object which has been written
  26.372 +     *       previously to the stream), an ObjectStreamException will be
  26.373 +     *       thrown.
  26.374 +     *
  26.375 +     *   <li>If readUnshared returns successfully, then any subsequent attempts
  26.376 +     *       to deserialize back-references to the stream handle deserialized
  26.377 +     *       by readUnshared will cause an ObjectStreamException to be thrown.
  26.378 +     * </ul>
  26.379 +     * Deserializing an object via readUnshared invalidates the stream handle
  26.380 +     * associated with the returned object.  Note that this in itself does not
  26.381 +     * always guarantee that the reference returned by readUnshared is unique;
  26.382 +     * the deserialized object may define a readResolve method which returns an
  26.383 +     * object visible to other parties, or readUnshared may return a Class
  26.384 +     * object or enum constant obtainable elsewhere in the stream or through
  26.385 +     * external means. If the deserialized object defines a readResolve method
  26.386 +     * and the invocation of that method returns an array, then readUnshared
  26.387 +     * returns a shallow clone of that array; this guarantees that the returned
  26.388 +     * array object is unique and cannot be obtained a second time from an
  26.389 +     * invocation of readObject or readUnshared on the ObjectInputStream,
  26.390 +     * even if the underlying data stream has been manipulated.
  26.391 +     *
  26.392 +     * <p>ObjectInputStream subclasses which override this method can only be
  26.393 +     * constructed in security contexts possessing the
  26.394 +     * "enableSubclassImplementation" SerializablePermission; any attempt to
  26.395 +     * instantiate such a subclass without this permission will cause a
  26.396 +     * SecurityException to be thrown.
  26.397 +     *
  26.398 +     * @return  reference to deserialized object
  26.399 +     * @throws  ClassNotFoundException if class of an object to deserialize
  26.400 +     *          cannot be found
  26.401 +     * @throws  StreamCorruptedException if control information in the stream
  26.402 +     *          is inconsistent
  26.403 +     * @throws  ObjectStreamException if object to deserialize has already
  26.404 +     *          appeared in stream
  26.405 +     * @throws  OptionalDataException if primitive data is next in stream
  26.406 +     * @throws  IOException if an I/O error occurs during deserialization
  26.407 +     * @since   1.4
  26.408 +     */
  26.409 +    public Object readUnshared() throws IOException, ClassNotFoundException {
  26.410 +        // if nested read, passHandle contains handle of enclosing object
  26.411 +        int outerHandle = passHandle;
  26.412 +        try {
  26.413 +            Object obj = readObject0(true);
  26.414 +            handles.markDependency(outerHandle, passHandle);
  26.415 +            ClassNotFoundException ex = handles.lookupException(passHandle);
  26.416 +            if (ex != null) {
  26.417 +                throw ex;
  26.418 +            }
  26.419 +            if (depth == 0) {
  26.420 +                vlist.doCallbacks();
  26.421 +            }
  26.422 +            return obj;
  26.423 +        } finally {
  26.424 +            passHandle = outerHandle;
  26.425 +            if (closed && depth == 0) {
  26.426 +                clear();
  26.427 +            }
  26.428 +        }
  26.429 +    }
  26.430 +
  26.431 +    /**
  26.432 +     * Read the non-static and non-transient fields of the current class from
  26.433 +     * this stream.  This may only be called from the readObject method of the
  26.434 +     * class being deserialized. It will throw the NotActiveException if it is
  26.435 +     * called otherwise.
  26.436 +     *
  26.437 +     * @throws  ClassNotFoundException if the class of a serialized object
  26.438 +     *          could not be found.
  26.439 +     * @throws  IOException if an I/O error occurs.
  26.440 +     * @throws  NotActiveException if the stream is not currently reading
  26.441 +     *          objects.
  26.442 +     */
  26.443 +    public void defaultReadObject()
  26.444 +        throws IOException, ClassNotFoundException
  26.445 +    {
  26.446 +        if (curContext == null) {
  26.447 +            throw new NotActiveException("not in call to readObject");
  26.448 +        }
  26.449 +        Object curObj = null; // curContext.getObj();
  26.450 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
  26.451 +        bin.setBlockDataMode(false);
  26.452 +        defaultReadFields(curObj, curDesc);
  26.453 +        bin.setBlockDataMode(true);
  26.454 +        if (!curDesc.hasWriteObjectData()) {
  26.455 +            /*
  26.456 +             * Fix for 4360508: since stream does not contain terminating
  26.457 +             * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
  26.458 +             * knows to simulate end-of-custom-data behavior.
  26.459 +             */
  26.460 +            defaultDataEnd = true;
  26.461 +        }
  26.462 +        ClassNotFoundException ex = handles.lookupException(passHandle);
  26.463 +        if (ex != null) {
  26.464 +            throw ex;
  26.465 +        }
  26.466 +    }
  26.467 +
  26.468 +    /**
  26.469 +     * Reads the persistent fields from the stream and makes them available by
  26.470 +     * name.
  26.471 +     *
  26.472 +     * @return  the <code>GetField</code> object representing the persistent
  26.473 +     *          fields of the object being deserialized
  26.474 +     * @throws  ClassNotFoundException if the class of a serialized object
  26.475 +     *          could not be found.
  26.476 +     * @throws  IOException if an I/O error occurs.
  26.477 +     * @throws  NotActiveException if the stream is not currently reading
  26.478 +     *          objects.
  26.479 +     * @since 1.2
  26.480 +     */
  26.481 +    public ObjectInputStream.GetField readFields()
  26.482 +        throws IOException, ClassNotFoundException
  26.483 +    {
  26.484 +        if (curContext == null) {
  26.485 +            throw new NotActiveException("not in call to readObject");
  26.486 +        }
  26.487 +        Object curObj = null; // curContext.getObj();
  26.488 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
  26.489 +        bin.setBlockDataMode(false);
  26.490 +        GetFieldImpl getField = new GetFieldImpl(curDesc);
  26.491 +        getField.readFields();
  26.492 +        bin.setBlockDataMode(true);
  26.493 +        if (!curDesc.hasWriteObjectData()) {
  26.494 +            /*
  26.495 +             * Fix for 4360508: since stream does not contain terminating
  26.496 +             * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
  26.497 +             * knows to simulate end-of-custom-data behavior.
  26.498 +             */
  26.499 +            defaultDataEnd = true;
  26.500 +        }
  26.501 +
  26.502 +        return getField;
  26.503 +    }
  26.504 +
  26.505 +    /**
  26.506 +     * Register an object to be validated before the graph is returned.  While
  26.507 +     * similar to resolveObject these validations are called after the entire
  26.508 +     * graph has been reconstituted.  Typically, a readObject method will
  26.509 +     * register the object with the stream so that when all of the objects are
  26.510 +     * restored a final set of validations can be performed.
  26.511 +     *
  26.512 +     * @param   obj the object to receive the validation callback.
  26.513 +     * @param   prio controls the order of callbacks;zero is a good default.
  26.514 +     *          Use higher numbers to be called back earlier, lower numbers for
  26.515 +     *          later callbacks. Within a priority, callbacks are processed in
  26.516 +     *          no particular order.
  26.517 +     * @throws  NotActiveException The stream is not currently reading objects
  26.518 +     *          so it is invalid to register a callback.
  26.519 +     * @throws  InvalidObjectException The validation object is null.
  26.520 +     */
  26.521 +    public void registerValidation(ObjectInputValidation obj, int prio)
  26.522 +        throws NotActiveException, InvalidObjectException
  26.523 +    {
  26.524 +        if (depth == 0) {
  26.525 +            throw new NotActiveException("stream inactive");
  26.526 +        }
  26.527 +        vlist.register(obj, prio);
  26.528 +    }
  26.529 +
  26.530 +    /**
  26.531 +     * Load the local class equivalent of the specified stream class
  26.532 +     * description.  Subclasses may implement this method to allow classes to
  26.533 +     * be fetched from an alternate source.
  26.534 +     *
  26.535 +     * <p>The corresponding method in <code>ObjectOutputStream</code> is
  26.536 +     * <code>annotateClass</code>.  This method will be invoked only once for
  26.537 +     * each unique class in the stream.  This method can be implemented by
  26.538 +     * subclasses to use an alternate loading mechanism but must return a
  26.539 +     * <code>Class</code> object. Once returned, if the class is not an array
  26.540 +     * class, its serialVersionUID is compared to the serialVersionUID of the
  26.541 +     * serialized class, and if there is a mismatch, the deserialization fails
  26.542 +     * and an {@link InvalidClassException} is thrown.
  26.543 +     *
  26.544 +     * <p>The default implementation of this method in
  26.545 +     * <code>ObjectInputStream</code> returns the result of calling
  26.546 +     * <pre>
  26.547 +     *     Class.forName(desc.getName(), false, loader)
  26.548 +     * </pre>
  26.549 +     * where <code>loader</code> is determined as follows: if there is a
  26.550 +     * method on the current thread's stack whose declaring class was
  26.551 +     * defined by a user-defined class loader (and was not a generated to
  26.552 +     * implement reflective invocations), then <code>loader</code> is class
  26.553 +     * loader corresponding to the closest such method to the currently
  26.554 +     * executing frame; otherwise, <code>loader</code> is
  26.555 +     * <code>null</code>. If this call results in a
  26.556 +     * <code>ClassNotFoundException</code> and the name of the passed
  26.557 +     * <code>ObjectStreamClass</code> instance is the Java language keyword
  26.558 +     * for a primitive type or void, then the <code>Class</code> object
  26.559 +     * representing that primitive type or void will be returned
  26.560 +     * (e.g., an <code>ObjectStreamClass</code> with the name
  26.561 +     * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
  26.562 +     * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
  26.563 +     * the caller of this method.
  26.564 +     *
  26.565 +     * @param   desc an instance of class <code>ObjectStreamClass</code>
  26.566 +     * @return  a <code>Class</code> object corresponding to <code>desc</code>
  26.567 +     * @throws  IOException any of the usual Input/Output exceptions.
  26.568 +     * @throws  ClassNotFoundException if class of a serialized object cannot
  26.569 +     *          be found.
  26.570 +     */
  26.571 +    protected Class<?> resolveClass(ObjectStreamClass desc)
  26.572 +        throws IOException, ClassNotFoundException
  26.573 +    {
  26.574 +        String name = desc.getName();
  26.575 +        try {
  26.576 +            return Class.forName(name, false, latestUserDefinedLoader());
  26.577 +        } catch (ClassNotFoundException ex) {
  26.578 +            Class<?> cl = primClasses.get(name);
  26.579 +            if (cl != null) {
  26.580 +                return cl;
  26.581 +            } else {
  26.582 +                throw ex;
  26.583 +            }
  26.584 +        }
  26.585 +    }
  26.586 +
  26.587 +    /**
  26.588 +     * Returns a proxy class that implements the interfaces named in a proxy
  26.589 +     * class descriptor; subclasses may implement this method to read custom
  26.590 +     * data from the stream along with the descriptors for dynamic proxy
  26.591 +     * classes, allowing them to use an alternate loading mechanism for the
  26.592 +     * interfaces and the proxy class.
  26.593 +     *
  26.594 +     * <p>This method is called exactly once for each unique proxy class
  26.595 +     * descriptor in the stream.
  26.596 +     *
  26.597 +     * <p>The corresponding method in <code>ObjectOutputStream</code> is
  26.598 +     * <code>annotateProxyClass</code>.  For a given subclass of
  26.599 +     * <code>ObjectInputStream</code> that overrides this method, the
  26.600 +     * <code>annotateProxyClass</code> method in the corresponding subclass of
  26.601 +     * <code>ObjectOutputStream</code> must write any data or objects read by
  26.602 +     * this method.
  26.603 +     *
  26.604 +     * <p>The default implementation of this method in
  26.605 +     * <code>ObjectInputStream</code> returns the result of calling
  26.606 +     * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
  26.607 +     * objects for the interfaces that are named in the <code>interfaces</code>
  26.608 +     * parameter.  The <code>Class</code> object for each interface name
  26.609 +     * <code>i</code> is the value returned by calling
  26.610 +     * <pre>
  26.611 +     *     Class.forName(i, false, loader)
  26.612 +     * </pre>
  26.613 +     * where <code>loader</code> is that of the first non-<code>null</code>
  26.614 +     * class loader up the execution stack, or <code>null</code> if no
  26.615 +     * non-<code>null</code> class loaders are on the stack (the same class
  26.616 +     * loader choice used by the <code>resolveClass</code> method).  Unless any
  26.617 +     * of the resolved interfaces are non-public, this same value of
  26.618 +     * <code>loader</code> is also the class loader passed to
  26.619 +     * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
  26.620 +     * their class loader is passed instead (if more than one non-public
  26.621 +     * interface class loader is encountered, an
  26.622 +     * <code>IllegalAccessError</code> is thrown).
  26.623 +     * If <code>Proxy.getProxyClass</code> throws an
  26.624 +     * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
  26.625 +     * will throw a <code>ClassNotFoundException</code> containing the
  26.626 +     * <code>IllegalArgumentException</code>.
  26.627 +     *
  26.628 +     * @param interfaces the list of interface names that were
  26.629 +     *                deserialized in the proxy class descriptor
  26.630 +     * @return  a proxy class for the specified interfaces
  26.631 +     * @throws        IOException any exception thrown by the underlying
  26.632 +     *                <code>InputStream</code>
  26.633 +     * @throws        ClassNotFoundException if the proxy class or any of the
  26.634 +     *                named interfaces could not be found
  26.635 +     * @see ObjectOutputStream#annotateProxyClass(Class)
  26.636 +     * @since 1.3
  26.637 +     */
  26.638 +    protected Class<?> resolveProxyClass(String[] interfaces)
  26.639 +        throws IOException, ClassNotFoundException
  26.640 +    {
  26.641 +        ClassLoader latestLoader = latestUserDefinedLoader();
  26.642 +        ClassLoader nonPublicLoader = null;
  26.643 +        boolean hasNonPublicInterface = false;
  26.644 +
  26.645 +        // define proxy in class loader of non-public interface(s), if any
  26.646 +        Class[] classObjs = new Class[interfaces.length];
  26.647 +        for (int i = 0; i < interfaces.length; i++) {
  26.648 +            Class cl = Class.forName(interfaces[i], false, latestLoader);
  26.649 +            if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
  26.650 +                if (hasNonPublicInterface) {
  26.651 +                    if (nonPublicLoader != cl.getClassLoader()) {
  26.652 +                        throw new IllegalAccessError(
  26.653 +                            "conflicting non-public interface class loaders");
  26.654 +                    }
  26.655 +                } else {
  26.656 +                    nonPublicLoader = cl.getClassLoader();
  26.657 +                    hasNonPublicInterface = true;
  26.658 +                }
  26.659 +            }
  26.660 +            classObjs[i] = cl;
  26.661 +        }
  26.662 +        try {
  26.663 +            return Proxy.getProxyClass(
  26.664 +                hasNonPublicInterface ? nonPublicLoader : latestLoader,
  26.665 +                classObjs);
  26.666 +        } catch (IllegalArgumentException e) {
  26.667 +            throw new ClassNotFoundException(null, e);
  26.668 +        }
  26.669 +    }
  26.670 +
  26.671 +    /**
  26.672 +     * This method will allow trusted subclasses of ObjectInputStream to
  26.673 +     * substitute one object for another during deserialization. Replacing
  26.674 +     * objects is disabled until enableResolveObject is called. The
  26.675 +     * enableResolveObject method checks that the stream requesting to resolve
  26.676 +     * object can be trusted. Every reference to serializable objects is passed
  26.677 +     * to resolveObject.  To insure that the private state of objects is not
  26.678 +     * unintentionally exposed only trusted streams may use resolveObject.
  26.679 +     *
  26.680 +     * <p>This method is called after an object has been read but before it is
  26.681 +     * returned from readObject.  The default resolveObject method just returns
  26.682 +     * the same object.
  26.683 +     *
  26.684 +     * <p>When a subclass is replacing objects it must insure that the
  26.685 +     * substituted object is compatible with every field where the reference
  26.686 +     * will be stored.  Objects whose type is not a subclass of the type of the
  26.687 +     * field or array element abort the serialization by raising an exception
  26.688 +     * and the object is not be stored.
  26.689 +     *
  26.690 +     * <p>This method is called only once when each object is first
  26.691 +     * encountered.  All subsequent references to the object will be redirected
  26.692 +     * to the new object.
  26.693 +     *
  26.694 +     * @param   obj object to be substituted
  26.695 +     * @return  the substituted object
  26.696 +     * @throws  IOException Any of the usual Input/Output exceptions.
  26.697 +     */
  26.698 +    protected Object resolveObject(Object obj) throws IOException {
  26.699 +        return obj;
  26.700 +    }
  26.701 +
  26.702 +    /**
  26.703 +     * Enable the stream to allow objects read from the stream to be replaced.
  26.704 +     * When enabled, the resolveObject method is called for every object being
  26.705 +     * deserialized.
  26.706 +     *
  26.707 +     * <p>If <i>enable</i> is true, and there is a security manager installed,
  26.708 +     * this method first calls the security manager's
  26.709 +     * <code>checkPermission</code> method with the
  26.710 +     * <code>SerializablePermission("enableSubstitution")</code> permission to
  26.711 +     * ensure it's ok to enable the stream to allow objects read from the
  26.712 +     * stream to be replaced.
  26.713 +     *
  26.714 +     * @param   enable true for enabling use of <code>resolveObject</code> for
  26.715 +     *          every object being deserialized
  26.716 +     * @return  the previous setting before this method was invoked
  26.717 +     * @throws  SecurityException if a security manager exists and its
  26.718 +     *          <code>checkPermission</code> method denies enabling the stream
  26.719 +     *          to allow objects read from the stream to be replaced.
  26.720 +     * @see SecurityManager#checkPermission
  26.721 +     * @see java.io.SerializablePermission
  26.722 +     */
  26.723 +    protected boolean enableResolveObject(boolean enable)
  26.724 +        throws SecurityException
  26.725 +    {
  26.726 +        throw new SecurityException();
  26.727 +    }
  26.728 +
  26.729 +    /**
  26.730 +     * The readStreamHeader method is provided to allow subclasses to read and
  26.731 +     * verify their own stream headers. It reads and verifies the magic number
  26.732 +     * and version number.
  26.733 +     *
  26.734 +     * @throws  IOException if there are I/O errors while reading from the
  26.735 +     *          underlying <code>InputStream</code>
  26.736 +     * @throws  StreamCorruptedException if control information in the stream
  26.737 +     *          is inconsistent
  26.738 +     */
  26.739 +    protected void readStreamHeader()
  26.740 +        throws IOException, StreamCorruptedException
  26.741 +    {
  26.742 +        short s0 = bin.readShort();
  26.743 +        short s1 = bin.readShort();
  26.744 +        if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
  26.745 +            throw new StreamCorruptedException(
  26.746 +                String.format("invalid stream header: %04X%04X", s0, s1));
  26.747 +        }
  26.748 +    }
  26.749 +
  26.750 +    /**
  26.751 +     * Read a class descriptor from the serialization stream.  This method is
  26.752 +     * called when the ObjectInputStream expects a class descriptor as the next
  26.753 +     * item in the serialization stream.  Subclasses of ObjectInputStream may
  26.754 +     * override this method to read in class descriptors that have been written
  26.755 +     * in non-standard formats (by subclasses of ObjectOutputStream which have
  26.756 +     * overridden the <code>writeClassDescriptor</code> method).  By default,
  26.757 +     * this method reads class descriptors according to the format defined in
  26.758 +     * the Object Serialization specification.
  26.759 +     *
  26.760 +     * @return  the class descriptor read
  26.761 +     * @throws  IOException If an I/O error has occurred.
  26.762 +     * @throws  ClassNotFoundException If the Class of a serialized object used
  26.763 +     *          in the class descriptor representation cannot be found
  26.764 +     * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass)
  26.765 +     * @since 1.3
  26.766 +     */
  26.767 +    protected ObjectStreamClass readClassDescriptor()
  26.768 +        throws IOException, ClassNotFoundException
  26.769 +    {
  26.770 +        ObjectStreamClass desc = new ObjectStreamClass();
  26.771 +        desc.readNonProxy(this);
  26.772 +        return desc;
  26.773 +    }
  26.774 +
  26.775 +    /**
  26.776 +     * Reads a byte of data. This method will block if no input is available.
  26.777 +     *
  26.778 +     * @return  the byte read, or -1 if the end of the stream is reached.
  26.779 +     * @throws  IOException If an I/O error has occurred.
  26.780 +     */
  26.781 +    public int read() throws IOException {
  26.782 +        return bin.read();
  26.783 +    }
  26.784 +
  26.785 +    /**
  26.786 +     * Reads into an array of bytes.  This method will block until some input
  26.787 +     * is available. Consider using java.io.DataInputStream.readFully to read
  26.788 +     * exactly 'length' bytes.
  26.789 +     *
  26.790 +     * @param   buf the buffer into which the data is read
  26.791 +     * @param   off the start offset of the data
  26.792 +     * @param   len the maximum number of bytes read
  26.793 +     * @return  the actual number of bytes read, -1 is returned when the end of
  26.794 +     *          the stream is reached.
  26.795 +     * @throws  IOException If an I/O error has occurred.
  26.796 +     * @see java.io.DataInputStream#readFully(byte[],int,int)
  26.797 +     */
  26.798 +    public int read(byte[] buf, int off, int len) throws IOException {
  26.799 +        if (buf == null) {
  26.800 +            throw new NullPointerException();
  26.801 +        }
  26.802 +        int endoff = off + len;
  26.803 +        if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
  26.804 +            throw new IndexOutOfBoundsException();
  26.805 +        }
  26.806 +        return bin.read(buf, off, len, false);
  26.807 +    }
  26.808 +
  26.809 +    /**
  26.810 +     * Returns the number of bytes that can be read without blocking.
  26.811 +     *
  26.812 +     * @return  the number of available bytes.
  26.813 +     * @throws  IOException if there are I/O errors while reading from the
  26.814 +     *          underlying <code>InputStream</code>
  26.815 +     */
  26.816 +    public int available() throws IOException {
  26.817 +        return bin.available();
  26.818 +    }
  26.819 +
  26.820 +    /**
  26.821 +     * Closes the input stream. Must be called to release any resources
  26.822 +     * associated with the stream.
  26.823 +     *
  26.824 +     * @throws  IOException If an I/O error has occurred.
  26.825 +     */
  26.826 +    public void close() throws IOException {
  26.827 +        /*
  26.828 +         * Even if stream already closed, propagate redundant close to
  26.829 +         * underlying stream to stay consistent with previous implementations.
  26.830 +         */
  26.831 +        closed = true;
  26.832 +        if (depth == 0) {
  26.833 +            clear();
  26.834 +        }
  26.835 +        bin.close();
  26.836 +    }
  26.837 +
  26.838 +    /**
  26.839 +     * Reads in a boolean.
  26.840 +     *
  26.841 +     * @return  the boolean read.
  26.842 +     * @throws  EOFException If end of file is reached.
  26.843 +     * @throws  IOException If other I/O error has occurred.
  26.844 +     */
  26.845 +    public boolean readBoolean() throws IOException {
  26.846 +        return bin.readBoolean();
  26.847 +    }
  26.848 +
  26.849 +    /**
  26.850 +     * Reads an 8 bit byte.
  26.851 +     *
  26.852 +     * @return  the 8 bit byte read.
  26.853 +     * @throws  EOFException If end of file is reached.
  26.854 +     * @throws  IOException If other I/O error has occurred.
  26.855 +     */
  26.856 +    public byte readByte() throws IOException  {
  26.857 +        return bin.readByte();
  26.858 +    }
  26.859 +
  26.860 +    /**
  26.861 +     * Reads an unsigned 8 bit byte.
  26.862 +     *
  26.863 +     * @return  the 8 bit byte read.
  26.864 +     * @throws  EOFException If end of file is reached.
  26.865 +     * @throws  IOException If other I/O error has occurred.
  26.866 +     */
  26.867 +    public int readUnsignedByte()  throws IOException {
  26.868 +        return bin.readUnsignedByte();
  26.869 +    }
  26.870 +
  26.871 +    /**
  26.872 +     * Reads a 16 bit char.
  26.873 +     *
  26.874 +     * @return  the 16 bit char read.
  26.875 +     * @throws  EOFException If end of file is reached.
  26.876 +     * @throws  IOException If other I/O error has occurred.
  26.877 +     */
  26.878 +    public char readChar()  throws IOException {
  26.879 +        return bin.readChar();
  26.880 +    }
  26.881 +
  26.882 +    /**
  26.883 +     * Reads a 16 bit short.
  26.884 +     *
  26.885 +     * @return  the 16 bit short read.
  26.886 +     * @throws  EOFException If end of file is reached.
  26.887 +     * @throws  IOException If other I/O error has occurred.
  26.888 +     */
  26.889 +    public short readShort()  throws IOException {
  26.890 +        return bin.readShort();
  26.891 +    }
  26.892 +
  26.893 +    /**
  26.894 +     * Reads an unsigned 16 bit short.
  26.895 +     *
  26.896 +     * @return  the 16 bit short read.
  26.897 +     * @throws  EOFException If end of file is reached.
  26.898 +     * @throws  IOException If other I/O error has occurred.
  26.899 +     */
  26.900 +    public int readUnsignedShort() throws IOException {
  26.901 +        return bin.readUnsignedShort();
  26.902 +    }
  26.903 +
  26.904 +    /**
  26.905 +     * Reads a 32 bit int.
  26.906 +     *
  26.907 +     * @return  the 32 bit integer read.
  26.908 +     * @throws  EOFException If end of file is reached.
  26.909 +     * @throws  IOException If other I/O error has occurred.
  26.910 +     */
  26.911 +    public int readInt()  throws IOException {
  26.912 +        return bin.readInt();
  26.913 +    }
  26.914 +
  26.915 +    /**
  26.916 +     * Reads a 64 bit long.
  26.917 +     *
  26.918 +     * @return  the read 64 bit long.
  26.919 +     * @throws  EOFException If end of file is reached.
  26.920 +     * @throws  IOException If other I/O error has occurred.
  26.921 +     */
  26.922 +    public long readLong()  throws IOException {
  26.923 +        return bin.readLong();
  26.924 +    }
  26.925 +
  26.926 +    /**
  26.927 +     * Reads a 32 bit float.
  26.928 +     *
  26.929 +     * @return  the 32 bit float read.
  26.930 +     * @throws  EOFException If end of file is reached.
  26.931 +     * @throws  IOException If other I/O error has occurred.
  26.932 +     */
  26.933 +    public float readFloat() throws IOException {
  26.934 +        return bin.readFloat();
  26.935 +    }
  26.936 +
  26.937 +    /**
  26.938 +     * Reads a 64 bit double.
  26.939 +     *
  26.940 +     * @return  the 64 bit double read.
  26.941 +     * @throws  EOFException If end of file is reached.
  26.942 +     * @throws  IOException If other I/O error has occurred.
  26.943 +     */
  26.944 +    public double readDouble() throws IOException {
  26.945 +        return bin.readDouble();
  26.946 +    }
  26.947 +
  26.948 +    /**
  26.949 +     * Reads bytes, blocking until all bytes are read.
  26.950 +     *
  26.951 +     * @param   buf the buffer into which the data is read
  26.952 +     * @throws  EOFException If end of file is reached.
  26.953 +     * @throws  IOException If other I/O error has occurred.
  26.954 +     */
  26.955 +    public void readFully(byte[] buf) throws IOException {
  26.956 +        bin.readFully(buf, 0, buf.length, false);
  26.957 +    }
  26.958 +
  26.959 +    /**
  26.960 +     * Reads bytes, blocking until all bytes are read.
  26.961 +     *
  26.962 +     * @param   buf the buffer into which the data is read
  26.963 +     * @param   off the start offset of the data
  26.964 +     * @param   len the maximum number of bytes to read
  26.965 +     * @throws  EOFException If end of file is reached.
  26.966 +     * @throws  IOException If other I/O error has occurred.
  26.967 +     */
  26.968 +    public void readFully(byte[] buf, int off, int len) throws IOException {
  26.969 +        int endoff = off + len;
  26.970 +        if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
  26.971 +            throw new IndexOutOfBoundsException();
  26.972 +        }
  26.973 +        bin.readFully(buf, off, len, false);
  26.974 +    }
  26.975 +
  26.976 +    /**
  26.977 +     * Skips bytes.
  26.978 +     *
  26.979 +     * @param   len the number of bytes to be skipped
  26.980 +     * @return  the actual number of bytes skipped.
  26.981 +     * @throws  IOException If an I/O error has occurred.
  26.982 +     */
  26.983 +    public int skipBytes(int len) throws IOException {
  26.984 +        return bin.skipBytes(len);
  26.985 +    }
  26.986 +
  26.987 +    /**
  26.988 +     * Reads in a line that has been terminated by a \n, \r, \r\n or EOF.
  26.989 +     *
  26.990 +     * @return  a String copy of the line.
  26.991 +     * @throws  IOException if there are I/O errors while reading from the
  26.992 +     *          underlying <code>InputStream</code>
  26.993 +     * @deprecated This method does not properly convert bytes to characters.
  26.994 +     *          see DataInputStream for the details and alternatives.
  26.995 +     */
  26.996 +    @Deprecated
  26.997 +    public String readLine() throws IOException {
  26.998 +        return bin.readLine();
  26.999 +    }
 26.1000 +
 26.1001 +    /**
 26.1002 +     * Reads a String in
 26.1003 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
 26.1004 +     * format.
 26.1005 +     *
 26.1006 +     * @return  the String.
 26.1007 +     * @throws  IOException if there are I/O errors while reading from the
 26.1008 +     *          underlying <code>InputStream</code>
 26.1009 +     * @throws  UTFDataFormatException if read bytes do not represent a valid
 26.1010 +     *          modified UTF-8 encoding of a string
 26.1011 +     */
 26.1012 +    public String readUTF() throws IOException {
 26.1013 +        return bin.readUTF();
 26.1014 +    }
 26.1015 +
 26.1016 +    /**
 26.1017 +     * Provide access to the persistent fields read from the input stream.
 26.1018 +     */
 26.1019 +    public static abstract class GetField {
 26.1020 +
 26.1021 +        /**
 26.1022 +         * Get the ObjectStreamClass that describes the fields in the stream.
 26.1023 +         *
 26.1024 +         * @return  the descriptor class that describes the serializable fields
 26.1025 +         */
 26.1026 +        public abstract ObjectStreamClass getObjectStreamClass();
 26.1027 +
 26.1028 +        /**
 26.1029 +         * Return true if the named field is defaulted and has no value in this
 26.1030 +         * stream.
 26.1031 +         *
 26.1032 +         * @param  name the name of the field
 26.1033 +         * @return true, if and only if the named field is defaulted
 26.1034 +         * @throws IOException if there are I/O errors while reading from
 26.1035 +         *         the underlying <code>InputStream</code>
 26.1036 +         * @throws IllegalArgumentException if <code>name</code> does not
 26.1037 +         *         correspond to a serializable field
 26.1038 +         */
 26.1039 +        public abstract boolean defaulted(String name) throws IOException;
 26.1040 +
 26.1041 +        /**
 26.1042 +         * Get the value of the named boolean field from the persistent field.
 26.1043 +         *
 26.1044 +         * @param  name the name of the field
 26.1045 +         * @param  val the default value to use if <code>name</code> does not
 26.1046 +         *         have a value
 26.1047 +         * @return the value of the named <code>boolean</code> field
 26.1048 +         * @throws IOException if there are I/O errors while reading from the
 26.1049 +         *         underlying <code>InputStream</code>
 26.1050 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1051 +         *         not serializable or if the field type is incorrect
 26.1052 +         */
 26.1053 +        public abstract boolean get(String name, boolean val)
 26.1054 +            throws IOException;
 26.1055 +
 26.1056 +        /**
 26.1057 +         * Get the value of the named byte field from the persistent field.
 26.1058 +         *
 26.1059 +         * @param  name the name of the field
 26.1060 +         * @param  val the default value to use if <code>name</code> does not
 26.1061 +         *         have a value
 26.1062 +         * @return the value of the named <code>byte</code> field
 26.1063 +         * @throws IOException if there are I/O errors while reading from the
 26.1064 +         *         underlying <code>InputStream</code>
 26.1065 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1066 +         *         not serializable or if the field type is incorrect
 26.1067 +         */
 26.1068 +        public abstract byte get(String name, byte val) throws IOException;
 26.1069 +
 26.1070 +        /**
 26.1071 +         * Get the value of the named char field from the persistent field.
 26.1072 +         *
 26.1073 +         * @param  name the name of the field
 26.1074 +         * @param  val the default value to use if <code>name</code> does not
 26.1075 +         *         have a value
 26.1076 +         * @return the value of the named <code>char</code> field
 26.1077 +         * @throws IOException if there are I/O errors while reading from the
 26.1078 +         *         underlying <code>InputStream</code>
 26.1079 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1080 +         *         not serializable or if the field type is incorrect
 26.1081 +         */
 26.1082 +        public abstract char get(String name, char val) throws IOException;
 26.1083 +
 26.1084 +        /**
 26.1085 +         * Get the value of the named short field from the persistent field.
 26.1086 +         *
 26.1087 +         * @param  name the name of the field
 26.1088 +         * @param  val the default value to use if <code>name</code> does not
 26.1089 +         *         have a value
 26.1090 +         * @return the value of the named <code>short</code> field
 26.1091 +         * @throws IOException if there are I/O errors while reading from the
 26.1092 +         *         underlying <code>InputStream</code>
 26.1093 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1094 +         *         not serializable or if the field type is incorrect
 26.1095 +         */
 26.1096 +        public abstract short get(String name, short val) throws IOException;
 26.1097 +
 26.1098 +        /**
 26.1099 +         * Get the value of the named int field from the persistent field.
 26.1100 +         *
 26.1101 +         * @param  name the name of the field
 26.1102 +         * @param  val the default value to use if <code>name</code> does not
 26.1103 +         *         have a value
 26.1104 +         * @return the value of the named <code>int</code> field
 26.1105 +         * @throws IOException if there are I/O errors while reading from the
 26.1106 +         *         underlying <code>InputStream</code>
 26.1107 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1108 +         *         not serializable or if the field type is incorrect
 26.1109 +         */
 26.1110 +        public abstract int get(String name, int val) throws IOException;
 26.1111 +
 26.1112 +        /**
 26.1113 +         * Get the value of the named long field from the persistent field.
 26.1114 +         *
 26.1115 +         * @param  name the name of the field
 26.1116 +         * @param  val the default value to use if <code>name</code> does not
 26.1117 +         *         have a value
 26.1118 +         * @return the value of the named <code>long</code> field
 26.1119 +         * @throws IOException if there are I/O errors while reading from the
 26.1120 +         *         underlying <code>InputStream</code>
 26.1121 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1122 +         *         not serializable or if the field type is incorrect
 26.1123 +         */
 26.1124 +        public abstract long get(String name, long val) throws IOException;
 26.1125 +
 26.1126 +        /**
 26.1127 +         * Get the value of the named float field from the persistent field.
 26.1128 +         *
 26.1129 +         * @param  name the name of the field
 26.1130 +         * @param  val the default value to use if <code>name</code> does not
 26.1131 +         *         have a value
 26.1132 +         * @return the value of the named <code>float</code> field
 26.1133 +         * @throws IOException if there are I/O errors while reading from the
 26.1134 +         *         underlying <code>InputStream</code>
 26.1135 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1136 +         *         not serializable or if the field type is incorrect
 26.1137 +         */
 26.1138 +        public abstract float get(String name, float val) throws IOException;
 26.1139 +
 26.1140 +        /**
 26.1141 +         * Get the value of the named double field from the persistent field.
 26.1142 +         *
 26.1143 +         * @param  name the name of the field
 26.1144 +         * @param  val the default value to use if <code>name</code> does not
 26.1145 +         *         have a value
 26.1146 +         * @return the value of the named <code>double</code> field
 26.1147 +         * @throws IOException if there are I/O errors while reading from the
 26.1148 +         *         underlying <code>InputStream</code>
 26.1149 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1150 +         *         not serializable or if the field type is incorrect
 26.1151 +         */
 26.1152 +        public abstract double get(String name, double val) throws IOException;
 26.1153 +
 26.1154 +        /**
 26.1155 +         * Get the value of the named Object field from the persistent field.
 26.1156 +         *
 26.1157 +         * @param  name the name of the field
 26.1158 +         * @param  val the default value to use if <code>name</code> does not
 26.1159 +         *         have a value
 26.1160 +         * @return the value of the named <code>Object</code> field
 26.1161 +         * @throws IOException if there are I/O errors while reading from the
 26.1162 +         *         underlying <code>InputStream</code>
 26.1163 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1164 +         *         not serializable or if the field type is incorrect
 26.1165 +         */
 26.1166 +        public abstract Object get(String name, Object val) throws IOException;
 26.1167 +    }
 26.1168 +
 26.1169 +    /**
 26.1170 +     * Verifies that this (possibly subclass) instance can be constructed
 26.1171 +     * without violating security constraints: the subclass must not override
 26.1172 +     * security-sensitive non-final methods, or else the
 26.1173 +     * "enableSubclassImplementation" SerializablePermission is checked.
 26.1174 +     */
 26.1175 +    private void verifySubclass() {
 26.1176 +        Class cl = getClass();
 26.1177 +        if (cl == ObjectInputStream.class) {
 26.1178 +            return;
 26.1179 +        }
 26.1180 +        throw new SecurityException();
 26.1181 +    }
 26.1182 +
 26.1183 +    /**
 26.1184 +     * Clears internal data structures.
 26.1185 +     */
 26.1186 +    private void clear() {
 26.1187 +        handles.clear();
 26.1188 +        vlist.clear();
 26.1189 +    }
 26.1190 +
 26.1191 +    /**
 26.1192 +     * Underlying readObject implementation.
 26.1193 +     */
 26.1194 +    private Object readObject0(boolean unshared) throws IOException {
 26.1195 +        boolean oldMode = bin.getBlockDataMode();
 26.1196 +        if (oldMode) {
 26.1197 +            int remain = bin.currentBlockRemaining();
 26.1198 +            if (remain > 0) {
 26.1199 +                throw new OptionalDataException(remain);
 26.1200 +            } else if (defaultDataEnd) {
 26.1201 +                /*
 26.1202 +                 * Fix for 4360508: stream is currently at the end of a field
 26.1203 +                 * value block written via default serialization; since there
 26.1204 +                 * is no terminating TC_ENDBLOCKDATA tag, simulate
 26.1205 +                 * end-of-custom-data behavior explicitly.
 26.1206 +                 */
 26.1207 +                throw new OptionalDataException(true);
 26.1208 +            }
 26.1209 +            bin.setBlockDataMode(false);
 26.1210 +        }
 26.1211 +
 26.1212 +        byte tc;
 26.1213 +        while ((tc = bin.peekByte()) == TC_RESET) {
 26.1214 +            bin.readByte();
 26.1215 +            handleReset();
 26.1216 +        }
 26.1217 +
 26.1218 +        depth++;
 26.1219 +        try {
 26.1220 +            switch (tc) {
 26.1221 +                case TC_NULL:
 26.1222 +                    return readNull();
 26.1223 +
 26.1224 +                case TC_REFERENCE:
 26.1225 +                    return readHandle(unshared);
 26.1226 +
 26.1227 +                case TC_CLASS:
 26.1228 +                    return readClass(unshared);
 26.1229 +
 26.1230 +                case TC_CLASSDESC:
 26.1231 +                case TC_PROXYCLASSDESC:
 26.1232 +                    return readClassDesc(unshared);
 26.1233 +
 26.1234 +                case TC_STRING:
 26.1235 +                case TC_LONGSTRING:
 26.1236 +                    return checkResolve(readString(unshared));
 26.1237 +
 26.1238 +                case TC_ARRAY:
 26.1239 +                    return checkResolve(readArray(unshared));
 26.1240 +
 26.1241 +                case TC_ENUM:
 26.1242 +                    return checkResolve(readEnum(unshared));
 26.1243 +
 26.1244 +                case TC_OBJECT:
 26.1245 +                    return checkResolve(readOrdinaryObject(unshared));
 26.1246 +
 26.1247 +                case TC_EXCEPTION:
 26.1248 +                    IOException ex = readFatalException();
 26.1249 +                    throw new WriteAbortedException("writing aborted", ex);
 26.1250 +
 26.1251 +                case TC_BLOCKDATA:
 26.1252 +                case TC_BLOCKDATALONG:
 26.1253 +                    if (oldMode) {
 26.1254 +                        bin.setBlockDataMode(true);
 26.1255 +                        bin.peek();             // force header read
 26.1256 +                        throw new OptionalDataException(
 26.1257 +                            bin.currentBlockRemaining());
 26.1258 +                    } else {
 26.1259 +                        throw new StreamCorruptedException(
 26.1260 +                            "unexpected block data");
 26.1261 +                    }
 26.1262 +
 26.1263 +                case TC_ENDBLOCKDATA:
 26.1264 +                    if (oldMode) {
 26.1265 +                        throw new OptionalDataException(true);
 26.1266 +                    } else {
 26.1267 +                        throw new StreamCorruptedException(
 26.1268 +                            "unexpected end of block data");
 26.1269 +                    }
 26.1270 +
 26.1271 +                default:
 26.1272 +                    throw new StreamCorruptedException(
 26.1273 +                        String.format("invalid type code: %02X", tc));
 26.1274 +            }
 26.1275 +        } finally {
 26.1276 +            depth--;
 26.1277 +            bin.setBlockDataMode(oldMode);
 26.1278 +        }
 26.1279 +    }
 26.1280 +
 26.1281 +    /**
 26.1282 +     * If resolveObject has been enabled and given object does not have an
 26.1283 +     * exception associated with it, calls resolveObject to determine
 26.1284 +     * replacement for object, and updates handle table accordingly.  Returns
 26.1285 +     * replacement object, or echoes provided object if no replacement
 26.1286 +     * occurred.  Expects that passHandle is set to given object's handle prior
 26.1287 +     * to calling this method.
 26.1288 +     */
 26.1289 +    private Object checkResolve(Object obj) throws IOException {
 26.1290 +        if (!enableResolve || handles.lookupException(passHandle) != null) {
 26.1291 +            return obj;
 26.1292 +        }
 26.1293 +        Object rep = resolveObject(obj);
 26.1294 +        if (rep != obj) {
 26.1295 +            handles.setObject(passHandle, rep);
 26.1296 +        }
 26.1297 +        return rep;
 26.1298 +    }
 26.1299 +
 26.1300 +    /**
 26.1301 +     * Reads string without allowing it to be replaced in stream.  Called from
 26.1302 +     * within ObjectStreamClass.read().
 26.1303 +     */
 26.1304 +    String readTypeString() throws IOException {
 26.1305 +        int oldHandle = passHandle;
 26.1306 +        try {
 26.1307 +            byte tc = bin.peekByte();
 26.1308 +            switch (tc) {
 26.1309 +                case TC_NULL:
 26.1310 +                    return (String) readNull();
 26.1311 +
 26.1312 +                case TC_REFERENCE:
 26.1313 +                    return (String) readHandle(false);
 26.1314 +
 26.1315 +                case TC_STRING:
 26.1316 +                case TC_LONGSTRING:
 26.1317 +                    return readString(false);
 26.1318 +
 26.1319 +                default:
 26.1320 +                    throw new StreamCorruptedException(
 26.1321 +                        String.format("invalid type code: %02X", tc));
 26.1322 +            }
 26.1323 +        } finally {
 26.1324 +            passHandle = oldHandle;
 26.1325 +        }
 26.1326 +    }
 26.1327 +
 26.1328 +    /**
 26.1329 +     * Reads in null code, sets passHandle to NULL_HANDLE and returns null.
 26.1330 +     */
 26.1331 +    private Object readNull() throws IOException {
 26.1332 +        if (bin.readByte() != TC_NULL) {
 26.1333 +            throw new InternalError();
 26.1334 +        }
 26.1335 +        passHandle = NULL_HANDLE;
 26.1336 +        return null;
 26.1337 +    }
 26.1338 +
 26.1339 +    /**
 26.1340 +     * Reads in object handle, sets passHandle to the read handle, and returns
 26.1341 +     * object associated with the handle.
 26.1342 +     */
 26.1343 +    private Object readHandle(boolean unshared) throws IOException {
 26.1344 +        if (bin.readByte() != TC_REFERENCE) {
 26.1345 +            throw new InternalError();
 26.1346 +        }
 26.1347 +        passHandle = bin.readInt() - baseWireHandle;
 26.1348 +        if (passHandle < 0 || passHandle >= handles.size()) {
 26.1349 +            throw new StreamCorruptedException(
 26.1350 +                String.format("invalid handle value: %08X", passHandle +
 26.1351 +                baseWireHandle));
 26.1352 +        }
 26.1353 +        if (unshared) {
 26.1354 +            // REMIND: what type of exception to throw here?
 26.1355 +            throw new InvalidObjectException(
 26.1356 +                "cannot read back reference as unshared");
 26.1357 +        }
 26.1358 +
 26.1359 +        Object obj = handles.lookupObject(passHandle);
 26.1360 +        if (obj == unsharedMarker) {
 26.1361 +            // REMIND: what type of exception to throw here?
 26.1362 +            throw new InvalidObjectException(
 26.1363 +                "cannot read back reference to unshared object");
 26.1364 +        }
 26.1365 +        return obj;
 26.1366 +    }
 26.1367 +
 26.1368 +    /**
 26.1369 +     * Reads in and returns class object.  Sets passHandle to class object's
 26.1370 +     * assigned handle.  Returns null if class is unresolvable (in which case a
 26.1371 +     * ClassNotFoundException will be associated with the class' handle in the
 26.1372 +     * handle table).
 26.1373 +     */
 26.1374 +    private Class readClass(boolean unshared) throws IOException {
 26.1375 +        if (bin.readByte() != TC_CLASS) {
 26.1376 +            throw new InternalError();
 26.1377 +        }
 26.1378 +        ObjectStreamClass desc = readClassDesc(false);
 26.1379 +        Class cl = desc.forClass();
 26.1380 +        passHandle = handles.assign(unshared ? unsharedMarker : cl);
 26.1381 +
 26.1382 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1383 +        if (resolveEx != null) {
 26.1384 +            handles.markException(passHandle, resolveEx);
 26.1385 +        }
 26.1386 +
 26.1387 +        handles.finish(passHandle);
 26.1388 +        return cl;
 26.1389 +    }
 26.1390 +
 26.1391 +    /**
 26.1392 +     * Reads in and returns (possibly null) class descriptor.  Sets passHandle
 26.1393 +     * to class descriptor's assigned handle.  If class descriptor cannot be
 26.1394 +     * resolved to a class in the local VM, a ClassNotFoundException is
 26.1395 +     * associated with the class descriptor's handle.
 26.1396 +     */
 26.1397 +    private ObjectStreamClass readClassDesc(boolean unshared)
 26.1398 +        throws IOException
 26.1399 +    {
 26.1400 +        byte tc = bin.peekByte();
 26.1401 +        switch (tc) {
 26.1402 +            case TC_NULL:
 26.1403 +                return (ObjectStreamClass) readNull();
 26.1404 +
 26.1405 +            case TC_REFERENCE:
 26.1406 +                return (ObjectStreamClass) readHandle(unshared);
 26.1407 +
 26.1408 +            case TC_PROXYCLASSDESC:
 26.1409 +                return readProxyDesc(unshared);
 26.1410 +
 26.1411 +            case TC_CLASSDESC:
 26.1412 +                return readNonProxyDesc(unshared);
 26.1413 +
 26.1414 +            default:
 26.1415 +                throw new StreamCorruptedException(
 26.1416 +                    String.format("invalid type code: %02X", tc));
 26.1417 +        }
 26.1418 +    }
 26.1419 +
 26.1420 +    /**
 26.1421 +     * Reads in and returns class descriptor for a dynamic proxy class.  Sets
 26.1422 +     * passHandle to proxy class descriptor's assigned handle.  If proxy class
 26.1423 +     * descriptor cannot be resolved to a class in the local VM, a
 26.1424 +     * ClassNotFoundException is associated with the descriptor's handle.
 26.1425 +     */
 26.1426 +    private ObjectStreamClass readProxyDesc(boolean unshared)
 26.1427 +        throws IOException
 26.1428 +    {
 26.1429 +        if (bin.readByte() != TC_PROXYCLASSDESC) {
 26.1430 +            throw new InternalError();
 26.1431 +        }
 26.1432 +
 26.1433 +        ObjectStreamClass desc = new ObjectStreamClass();
 26.1434 +        int descHandle = handles.assign(unshared ? unsharedMarker : desc);
 26.1435 +        passHandle = NULL_HANDLE;
 26.1436 +
 26.1437 +        int numIfaces = bin.readInt();
 26.1438 +        String[] ifaces = new String[numIfaces];
 26.1439 +        for (int i = 0; i < numIfaces; i++) {
 26.1440 +            ifaces[i] = bin.readUTF();
 26.1441 +        }
 26.1442 +
 26.1443 +        Class cl = null;
 26.1444 +        ClassNotFoundException resolveEx = null;
 26.1445 +        bin.setBlockDataMode(true);
 26.1446 +        try {
 26.1447 +            if ((cl = resolveProxyClass(ifaces)) == null) {
 26.1448 +                resolveEx = new ClassNotFoundException("null class");
 26.1449 +            }
 26.1450 +        } catch (ClassNotFoundException ex) {
 26.1451 +            resolveEx = ex;
 26.1452 +        }
 26.1453 +        skipCustomData();
 26.1454 +
 26.1455 +        desc.initProxy(cl, resolveEx, readClassDesc(false));
 26.1456 +
 26.1457 +        handles.finish(descHandle);
 26.1458 +        passHandle = descHandle;
 26.1459 +        return desc;
 26.1460 +    }
 26.1461 +
 26.1462 +    /**
 26.1463 +     * Reads in and returns class descriptor for a class that is not a dynamic
 26.1464 +     * proxy class.  Sets passHandle to class descriptor's assigned handle.  If
 26.1465 +     * class descriptor cannot be resolved to a class in the local VM, a
 26.1466 +     * ClassNotFoundException is associated with the descriptor's handle.
 26.1467 +     */
 26.1468 +    private ObjectStreamClass readNonProxyDesc(boolean unshared)
 26.1469 +        throws IOException
 26.1470 +    {
 26.1471 +        if (bin.readByte() != TC_CLASSDESC) {
 26.1472 +            throw new InternalError();
 26.1473 +        }
 26.1474 +
 26.1475 +        ObjectStreamClass desc = new ObjectStreamClass();
 26.1476 +        int descHandle = handles.assign(unshared ? unsharedMarker : desc);
 26.1477 +        passHandle = NULL_HANDLE;
 26.1478 +
 26.1479 +        ObjectStreamClass readDesc = null;
 26.1480 +        try {
 26.1481 +            readDesc = readClassDescriptor();
 26.1482 +        } catch (ClassNotFoundException ex) {
 26.1483 +            throw (IOException) new InvalidClassException(
 26.1484 +                "failed to read class descriptor").initCause(ex);
 26.1485 +        }
 26.1486 +
 26.1487 +        Class cl = null;
 26.1488 +        ClassNotFoundException resolveEx = null;
 26.1489 +        bin.setBlockDataMode(true);
 26.1490 +        try {
 26.1491 +            if ((cl = resolveClass(readDesc)) == null) {
 26.1492 +                resolveEx = new ClassNotFoundException("null class");
 26.1493 +            }
 26.1494 +        } catch (ClassNotFoundException ex) {
 26.1495 +            resolveEx = ex;
 26.1496 +        }
 26.1497 +        skipCustomData();
 26.1498 +
 26.1499 +        desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
 26.1500 +
 26.1501 +        handles.finish(descHandle);
 26.1502 +        passHandle = descHandle;
 26.1503 +        return desc;
 26.1504 +    }
 26.1505 +
 26.1506 +    /**
 26.1507 +     * Reads in and returns new string.  Sets passHandle to new string's
 26.1508 +     * assigned handle.
 26.1509 +     */
 26.1510 +    private String readString(boolean unshared) throws IOException {
 26.1511 +        String str;
 26.1512 +        byte tc = bin.readByte();
 26.1513 +        switch (tc) {
 26.1514 +            case TC_STRING:
 26.1515 +                str = bin.readUTF();
 26.1516 +                break;
 26.1517 +
 26.1518 +            case TC_LONGSTRING:
 26.1519 +                str = bin.readLongUTF();
 26.1520 +                break;
 26.1521 +
 26.1522 +            default:
 26.1523 +                throw new StreamCorruptedException(
 26.1524 +                    String.format("invalid type code: %02X", tc));
 26.1525 +        }
 26.1526 +        passHandle = handles.assign(unshared ? unsharedMarker : str);
 26.1527 +        handles.finish(passHandle);
 26.1528 +        return str;
 26.1529 +    }
 26.1530 +
 26.1531 +    /**
 26.1532 +     * Reads in and returns array object, or null if array class is
 26.1533 +     * unresolvable.  Sets passHandle to array's assigned handle.
 26.1534 +     */
 26.1535 +    private Object readArray(boolean unshared) throws IOException {
 26.1536 +        if (bin.readByte() != TC_ARRAY) {
 26.1537 +            throw new InternalError();
 26.1538 +        }
 26.1539 +
 26.1540 +        ObjectStreamClass desc = readClassDesc(false);
 26.1541 +        int len = bin.readInt();
 26.1542 +
 26.1543 +        Object array = null;
 26.1544 +        Class cl, ccl = null;
 26.1545 +        if ((cl = desc.forClass()) != null) {
 26.1546 +            ccl = cl.getComponentType();
 26.1547 +            array = Array.newInstance(ccl, len);
 26.1548 +        }
 26.1549 +
 26.1550 +        int arrayHandle = handles.assign(unshared ? unsharedMarker : array);
 26.1551 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1552 +        if (resolveEx != null) {
 26.1553 +            handles.markException(arrayHandle, resolveEx);
 26.1554 +        }
 26.1555 +
 26.1556 +        if (ccl == null) {
 26.1557 +            for (int i = 0; i < len; i++) {
 26.1558 +                readObject0(false);
 26.1559 +            }
 26.1560 +        } else if (ccl.isPrimitive()) {
 26.1561 +            if (ccl == Integer.TYPE) {
 26.1562 +                bin.readInts((int[]) array, 0, len);
 26.1563 +            } else if (ccl == Byte.TYPE) {
 26.1564 +                bin.readFully((byte[]) array, 0, len, true);
 26.1565 +            } else if (ccl == Long.TYPE) {
 26.1566 +                bin.readLongs((long[]) array, 0, len);
 26.1567 +            } else if (ccl == Float.TYPE) {
 26.1568 +                bin.readFloats((float[]) array, 0, len);
 26.1569 +            } else if (ccl == Double.TYPE) {
 26.1570 +                bin.readDoubles((double[]) array, 0, len);
 26.1571 +            } else if (ccl == Short.TYPE) {
 26.1572 +                bin.readShorts((short[]) array, 0, len);
 26.1573 +            } else if (ccl == Character.TYPE) {
 26.1574 +                bin.readChars((char[]) array, 0, len);
 26.1575 +            } else if (ccl == Boolean.TYPE) {
 26.1576 +                bin.readBooleans((boolean[]) array, 0, len);
 26.1577 +            } else {
 26.1578 +                throw new InternalError();
 26.1579 +            }
 26.1580 +        } else {
 26.1581 +            Object[] oa = (Object[]) array;
 26.1582 +            for (int i = 0; i < len; i++) {
 26.1583 +                oa[i] = readObject0(false);
 26.1584 +                handles.markDependency(arrayHandle, passHandle);
 26.1585 +            }
 26.1586 +        }
 26.1587 +
 26.1588 +        handles.finish(arrayHandle);
 26.1589 +        passHandle = arrayHandle;
 26.1590 +        return array;
 26.1591 +    }
 26.1592 +
 26.1593 +    /**
 26.1594 +     * Reads in and returns enum constant, or null if enum type is
 26.1595 +     * unresolvable.  Sets passHandle to enum constant's assigned handle.
 26.1596 +     */
 26.1597 +    private Enum readEnum(boolean unshared) throws IOException {
 26.1598 +        if (bin.readByte() != TC_ENUM) {
 26.1599 +            throw new InternalError();
 26.1600 +        }
 26.1601 +
 26.1602 +        ObjectStreamClass desc = readClassDesc(false);
 26.1603 +        if (!desc.isEnum()) {
 26.1604 +            throw new InvalidClassException("non-enum class: " + desc);
 26.1605 +        }
 26.1606 +
 26.1607 +        int enumHandle = handles.assign(unshared ? unsharedMarker : null);
 26.1608 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1609 +        if (resolveEx != null) {
 26.1610 +            handles.markException(enumHandle, resolveEx);
 26.1611 +        }
 26.1612 +
 26.1613 +        String name = readString(false);
 26.1614 +        Enum en = null;
 26.1615 +        Class cl = desc.forClass();
 26.1616 +        if (cl != null) {
 26.1617 +            try {
 26.1618 +                en = Enum.valueOf(cl, name);
 26.1619 +            } catch (IllegalArgumentException ex) {
 26.1620 +                throw (IOException) new InvalidObjectException(
 26.1621 +                    "enum constant " + name + " does not exist in " +
 26.1622 +                    cl).initCause(ex);
 26.1623 +            }
 26.1624 +            if (!unshared) {
 26.1625 +                handles.setObject(enumHandle, en);
 26.1626 +            }
 26.1627 +        }
 26.1628 +
 26.1629 +        handles.finish(enumHandle);
 26.1630 +        passHandle = enumHandle;
 26.1631 +        return en;
 26.1632 +    }
 26.1633 +
 26.1634 +    /**
 26.1635 +     * Reads and returns "ordinary" (i.e., not a String, Class,
 26.1636 +     * ObjectStreamClass, array, or enum constant) object, or null if object's
 26.1637 +     * class is unresolvable (in which case a ClassNotFoundException will be
 26.1638 +     * associated with object's handle).  Sets passHandle to object's assigned
 26.1639 +     * handle.
 26.1640 +     */
 26.1641 +    private Object readOrdinaryObject(boolean unshared)
 26.1642 +        throws IOException
 26.1643 +    {
 26.1644 +        if (bin.readByte() != TC_OBJECT) {
 26.1645 +            throw new InternalError();
 26.1646 +        }
 26.1647 +
 26.1648 +        ObjectStreamClass desc = readClassDesc(false);
 26.1649 +        desc.checkDeserialize();
 26.1650 +
 26.1651 +        Object obj;
 26.1652 +        try {
 26.1653 +            obj = desc.isInstantiable() ? desc.newInstance() : null;
 26.1654 +        } catch (Exception ex) {
 26.1655 +            throw (IOException) new InvalidClassException(
 26.1656 +                desc.forClass().getName(),
 26.1657 +                "unable to create instance").initCause(ex);
 26.1658 +        }
 26.1659 +
 26.1660 +        passHandle = handles.assign(unshared ? unsharedMarker : obj);
 26.1661 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1662 +        if (resolveEx != null) {
 26.1663 +            handles.markException(passHandle, resolveEx);
 26.1664 +        }
 26.1665 +
 26.1666 +        if (desc.isExternalizable()) {
 26.1667 +            readExternalData((Externalizable) obj, desc);
 26.1668 +        } else {
 26.1669 +            readSerialData(obj, desc);
 26.1670 +        }
 26.1671 +
 26.1672 +        handles.finish(passHandle);
 26.1673 +
 26.1674 +        if (obj != null &&
 26.1675 +            handles.lookupException(passHandle) == null &&
 26.1676 +            desc.hasReadResolveMethod())
 26.1677 +        {
 26.1678 +            Object rep = desc.invokeReadResolve(obj);
 26.1679 +            if (unshared && rep.getClass().isArray()) {
 26.1680 +                rep = cloneArray(rep);
 26.1681 +            }
 26.1682 +            if (rep != obj) {
 26.1683 +                handles.setObject(passHandle, obj = rep);
 26.1684 +            }
 26.1685 +        }
 26.1686 +
 26.1687 +        return obj;
 26.1688 +    }
 26.1689 +
 26.1690 +    /**
 26.1691 +     * If obj is non-null, reads externalizable data by invoking readExternal()
 26.1692 +     * method of obj; otherwise, attempts to skip over externalizable data.
 26.1693 +     * Expects that passHandle is set to obj's handle before this method is
 26.1694 +     * called.
 26.1695 +     */
 26.1696 +    private void readExternalData(Externalizable obj, ObjectStreamClass desc)
 26.1697 +        throws IOException
 26.1698 +    {
 26.1699 +        Object oldContext = curContext;
 26.1700 +        curContext = null;
 26.1701 +        try {
 26.1702 +            boolean blocked = desc.hasBlockExternalData();
 26.1703 +            if (blocked) {
 26.1704 +                bin.setBlockDataMode(true);
 26.1705 +            }
 26.1706 +            if (obj != null) {
 26.1707 +                try {
 26.1708 +                    obj.readExternal(this);
 26.1709 +                } catch (ClassNotFoundException ex) {
 26.1710 +                    /*
 26.1711 +                     * In most cases, the handle table has already propagated
 26.1712 +                     * a CNFException to passHandle at this point; this mark
 26.1713 +                     * call is included to address cases where the readExternal
 26.1714 +                     * method has cons'ed and thrown a new CNFException of its
 26.1715 +                     * own.
 26.1716 +                     */
 26.1717 +                     handles.markException(passHandle, ex);
 26.1718 +                }
 26.1719 +            }
 26.1720 +            if (blocked) {
 26.1721 +                skipCustomData();
 26.1722 +            }
 26.1723 +        } finally {
 26.1724 +            curContext = oldContext;
 26.1725 +        }
 26.1726 +        /*
 26.1727 +         * At this point, if the externalizable data was not written in
 26.1728 +         * block-data form and either the externalizable class doesn't exist
 26.1729 +         * locally (i.e., obj == null) or readExternal() just threw a
 26.1730 +         * CNFException, then the stream is probably in an inconsistent state,
 26.1731 +         * since some (or all) of the externalizable data may not have been
 26.1732 +         * consumed.  Since there's no "correct" action to take in this case,
 26.1733 +         * we mimic the behavior of past serialization implementations and
 26.1734 +         * blindly hope that the stream is in sync; if it isn't and additional
 26.1735 +         * externalizable data remains in the stream, a subsequent read will
 26.1736 +         * most likely throw a StreamCorruptedException.
 26.1737 +         */
 26.1738 +    }
 26.1739 +
 26.1740 +    /**
 26.1741 +     * Reads (or attempts to skip, if obj is null or is tagged with a
 26.1742 +     * ClassNotFoundException) instance data for each serializable class of
 26.1743 +     * object in stream, from superclass to subclass.  Expects that passHandle
 26.1744 +     * is set to obj's handle before this method is called.
 26.1745 +     */
 26.1746 +    private void readSerialData(Object obj, ObjectStreamClass desc)
 26.1747 +        throws IOException
 26.1748 +    {
 26.1749 +        ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
 26.1750 +        for (int i = 0; i < slots.length; i++) {
 26.1751 +            ObjectStreamClass slotDesc = slots[i].desc;
 26.1752 +
 26.1753 +            if (slots[i].hasData) {
 26.1754 +                if (obj != null &&
 26.1755 +                    slotDesc.hasReadObjectMethod() &&
 26.1756 +                    handles.lookupException(passHandle) == null)
 26.1757 +                {
 26.1758 +                    Object oldContext = curContext;
 26.1759 +
 26.1760 +                    try {
 26.1761 +                        curContext = null; //new SerialCallbackContext(obj, slotDesc);
 26.1762 +
 26.1763 +                        bin.setBlockDataMode(true);
 26.1764 +                        slotDesc.invokeReadObject(obj, this);
 26.1765 +                    } catch (ClassNotFoundException ex) {
 26.1766 +                        /*
 26.1767 +                         * In most cases, the handle table has already
 26.1768 +                         * propagated a CNFException to passHandle at this
 26.1769 +                         * point; this mark call is included to address cases
 26.1770 +                         * where the custom readObject method has cons'ed and
 26.1771 +                         * thrown a new CNFException of its own.
 26.1772 +                         */
 26.1773 +                        handles.markException(passHandle, ex);
 26.1774 +                    } finally {
 26.1775 +                        //curContext.setUsed();
 26.1776 +                        curContext = oldContext;
 26.1777 +                    }
 26.1778 +
 26.1779 +                    /*
 26.1780 +                     * defaultDataEnd may have been set indirectly by custom
 26.1781 +                     * readObject() method when calling defaultReadObject() or
 26.1782 +                     * readFields(); clear it to restore normal read behavior.
 26.1783 +                     */
 26.1784 +                    defaultDataEnd = false;
 26.1785 +                } else {
 26.1786 +                    defaultReadFields(obj, slotDesc);
 26.1787 +                }
 26.1788 +                if (slotDesc.hasWriteObjectData()) {
 26.1789 +                    skipCustomData();
 26.1790 +                } else {
 26.1791 +                    bin.setBlockDataMode(false);
 26.1792 +                }
 26.1793 +            } else {
 26.1794 +                if (obj != null &&
 26.1795 +                    slotDesc.hasReadObjectNoDataMethod() &&
 26.1796 +                    handles.lookupException(passHandle) == null)
 26.1797 +                {
 26.1798 +                    slotDesc.invokeReadObjectNoData(obj);
 26.1799 +                }
 26.1800 +            }
 26.1801 +        }
 26.1802 +    }
 26.1803 +
 26.1804 +    /**
 26.1805 +     * Skips over all block data and objects until TC_ENDBLOCKDATA is
 26.1806 +     * encountered.
 26.1807 +     */
 26.1808 +    private void skipCustomData() throws IOException {
 26.1809 +        int oldHandle = passHandle;
 26.1810 +        for (;;) {
 26.1811 +            if (bin.getBlockDataMode()) {
 26.1812 +                bin.skipBlockData();
 26.1813 +                bin.setBlockDataMode(false);
 26.1814 +            }
 26.1815 +            switch (bin.peekByte()) {
 26.1816 +                case TC_BLOCKDATA:
 26.1817 +                case TC_BLOCKDATALONG:
 26.1818 +                    bin.setBlockDataMode(true);
 26.1819 +                    break;
 26.1820 +
 26.1821 +                case TC_ENDBLOCKDATA:
 26.1822 +                    bin.readByte();
 26.1823 +                    passHandle = oldHandle;
 26.1824 +                    return;
 26.1825 +
 26.1826 +                default:
 26.1827 +                    readObject0(false);
 26.1828 +                    break;
 26.1829 +            }
 26.1830 +        }
 26.1831 +    }
 26.1832 +
 26.1833 +    /**
 26.1834 +     * Reads in values of serializable fields declared by given class
 26.1835 +     * descriptor.  If obj is non-null, sets field values in obj.  Expects that
 26.1836 +     * passHandle is set to obj's handle before this method is called.
 26.1837 +     */
 26.1838 +    private void defaultReadFields(Object obj, ObjectStreamClass desc)
 26.1839 +        throws IOException
 26.1840 +    {
 26.1841 +        // REMIND: is isInstance check necessary?
 26.1842 +        Class cl = desc.forClass();
 26.1843 +        if (cl != null && obj != null && !cl.isInstance(obj)) {
 26.1844 +            throw new ClassCastException();
 26.1845 +        }
 26.1846 +
 26.1847 +        int primDataSize = desc.getPrimDataSize();
 26.1848 +        if (primVals == null || primVals.length < primDataSize) {
 26.1849 +            primVals = new byte[primDataSize];
 26.1850 +        }
 26.1851 +        bin.readFully(primVals, 0, primDataSize, false);
 26.1852 +        if (obj != null) {
 26.1853 +            desc.setPrimFieldValues(obj, primVals);
 26.1854 +        }
 26.1855 +
 26.1856 +        int objHandle = passHandle;
 26.1857 +        ObjectStreamField[] fields = desc.getFields(false);
 26.1858 +        Object[] objVals = new Object[desc.getNumObjFields()];
 26.1859 +        int numPrimFields = fields.length - objVals.length;
 26.1860 +        for (int i = 0; i < objVals.length; i++) {
 26.1861 +            ObjectStreamField f = fields[numPrimFields + i];
 26.1862 +            objVals[i] = readObject0(f.isUnshared());
 26.1863 +            if (f.getField() != null) {
 26.1864 +                handles.markDependency(objHandle, passHandle);
 26.1865 +            }
 26.1866 +        }
 26.1867 +        if (obj != null) {
 26.1868 +            desc.setObjFieldValues(obj, objVals);
 26.1869 +        }
 26.1870 +        passHandle = objHandle;
 26.1871 +    }
 26.1872 +
 26.1873 +    /**
 26.1874 +     * Reads in and returns IOException that caused serialization to abort.
 26.1875 +     * All stream state is discarded prior to reading in fatal exception.  Sets
 26.1876 +     * passHandle to fatal exception's handle.
 26.1877 +     */
 26.1878 +    private IOException readFatalException() throws IOException {
 26.1879 +        if (bin.readByte() != TC_EXCEPTION) {
 26.1880 +            throw new InternalError();
 26.1881 +        }
 26.1882 +        clear();
 26.1883 +        return (IOException) readObject0(false);
 26.1884 +    }
 26.1885 +
 26.1886 +    /**
 26.1887 +     * If recursion depth is 0, clears internal data structures; otherwise,
 26.1888 +     * throws a StreamCorruptedException.  This method is called when a
 26.1889 +     * TC_RESET typecode is encountered.
 26.1890 +     */
 26.1891 +    private void handleReset() throws StreamCorruptedException {
 26.1892 +        if (depth > 0) {
 26.1893 +            throw new StreamCorruptedException(
 26.1894 +                "unexpected reset; recursion depth: " + depth);
 26.1895 +        }
 26.1896 +        clear();
 26.1897 +    }
 26.1898 +
 26.1899 +    /**
 26.1900 +     * Converts specified span of bytes into float values.
 26.1901 +     */
 26.1902 +    // REMIND: remove once hotspot inlines Float.intBitsToFloat
 26.1903 +    private static native void bytesToFloats(byte[] src, int srcpos,
 26.1904 +                                             float[] dst, int dstpos,
 26.1905 +                                             int nfloats);
 26.1906 +
 26.1907 +    /**
 26.1908 +     * Converts specified span of bytes into double values.
 26.1909 +     */
 26.1910 +    // REMIND: remove once hotspot inlines Double.longBitsToDouble
 26.1911 +    private static native void bytesToDoubles(byte[] src, int srcpos,
 26.1912 +                                              double[] dst, int dstpos,
 26.1913 +                                              int ndoubles);
 26.1914 +
 26.1915 +    /**
 26.1916 +     * Returns the first non-null class loader (not counting class loaders of
 26.1917 +     * generated reflection implementation classes) up the execution stack, or
 26.1918 +     * null if only code from the null class loader is on the stack.  This
 26.1919 +     * method is also called via reflection by the following RMI-IIOP class:
 26.1920 +     *
 26.1921 +     *     com.sun.corba.se.internal.util.JDKClassLoader
 26.1922 +     *
 26.1923 +     * This method should not be removed or its signature changed without
 26.1924 +     * corresponding modifications to the above class.
 26.1925 +     */
 26.1926 +    // REMIND: change name to something more accurate?
 26.1927 +    private static native ClassLoader latestUserDefinedLoader();
 26.1928 +
 26.1929 +    /**
 26.1930 +     * Default GetField implementation.
 26.1931 +     */
 26.1932 +    private class GetFieldImpl extends GetField {
 26.1933 +
 26.1934 +        /** class descriptor describing serializable fields */
 26.1935 +        private final ObjectStreamClass desc;
 26.1936 +        /** primitive field values */
 26.1937 +        private final byte[] primVals;
 26.1938 +        /** object field values */
 26.1939 +        private final Object[] objVals;
 26.1940 +        /** object field value handles */
 26.1941 +        private final int[] objHandles;
 26.1942 +
 26.1943 +        /**
 26.1944 +         * Creates GetFieldImpl object for reading fields defined in given
 26.1945 +         * class descriptor.
 26.1946 +         */
 26.1947 +        GetFieldImpl(ObjectStreamClass desc) {
 26.1948 +            this.desc = desc;
 26.1949 +            primVals = new byte[desc.getPrimDataSize()];
 26.1950 +            objVals = new Object[desc.getNumObjFields()];
 26.1951 +            objHandles = new int[objVals.length];
 26.1952 +        }
 26.1953 +
 26.1954 +        public ObjectStreamClass getObjectStreamClass() {
 26.1955 +            return desc;
 26.1956 +        }
 26.1957 +
 26.1958 +        public boolean defaulted(String name) throws IOException {
 26.1959 +            return (getFieldOffset(name, null) < 0);
 26.1960 +        }
 26.1961 +
 26.1962 +        public boolean get(String name, boolean val) throws IOException {
 26.1963 +            int off = getFieldOffset(name, Boolean.TYPE);
 26.1964 +            return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
 26.1965 +        }
 26.1966 +
 26.1967 +        public byte get(String name, byte val) throws IOException {
 26.1968 +            int off = getFieldOffset(name, Byte.TYPE);
 26.1969 +            return (off >= 0) ? primVals[off] : val;
 26.1970 +        }
 26.1971 +
 26.1972 +        public char get(String name, char val) throws IOException {
 26.1973 +            int off = getFieldOffset(name, Character.TYPE);
 26.1974 +            return (off >= 0) ? Bits.getChar(primVals, off) : val;
 26.1975 +        }
 26.1976 +
 26.1977 +        public short get(String name, short val) throws IOException {
 26.1978 +            int off = getFieldOffset(name, Short.TYPE);
 26.1979 +            return (off >= 0) ? Bits.getShort(primVals, off) : val;
 26.1980 +        }
 26.1981 +
 26.1982 +        public int get(String name, int val) throws IOException {
 26.1983 +            int off = getFieldOffset(name, Integer.TYPE);
 26.1984 +            return (off >= 0) ? Bits.getInt(primVals, off) : val;
 26.1985 +        }
 26.1986 +
 26.1987 +        public float get(String name, float val) throws IOException {
 26.1988 +            int off = getFieldOffset(name, Float.TYPE);
 26.1989 +            return (off >= 0) ? Bits.getFloat(primVals, off) : val;
 26.1990 +        }
 26.1991 +
 26.1992 +        public long get(String name, long val) throws IOException {
 26.1993 +            int off = getFieldOffset(name, Long.TYPE);
 26.1994 +            return (off >= 0) ? Bits.getLong(primVals, off) : val;
 26.1995 +        }
 26.1996 +
 26.1997 +        public double get(String name, double val) throws IOException {
 26.1998 +            int off = getFieldOffset(name, Double.TYPE);
 26.1999 +            return (off >= 0) ? Bits.getDouble(primVals, off) : val;
 26.2000 +        }
 26.2001 +
 26.2002 +        public Object get(String name, Object val) throws IOException {
 26.2003 +            int off = getFieldOffset(name, Object.class);
 26.2004 +            if (off >= 0) {
 26.2005 +                int objHandle = objHandles[off];
 26.2006 +                handles.markDependency(passHandle, objHandle);
 26.2007 +                return (handles.lookupException(objHandle) == null) ?
 26.2008 +                    objVals[off] : null;
 26.2009 +            } else {
 26.2010 +                return val;
 26.2011 +            }
 26.2012 +        }
 26.2013 +
 26.2014 +        /**
 26.2015 +         * Reads primitive and object field values from stream.
 26.2016 +         */
 26.2017 +        void readFields() throws IOException {
 26.2018 +            bin.readFully(primVals, 0, primVals.length, false);
 26.2019 +
 26.2020 +            int oldHandle = passHandle;
 26.2021 +            ObjectStreamField[] fields = desc.getFields(false);
 26.2022 +            int numPrimFields = fields.length - objVals.length;
 26.2023 +            for (int i = 0; i < objVals.length; i++) {
 26.2024 +                objVals[i] =
 26.2025 +                    readObject0(fields[numPrimFields + i].isUnshared());
 26.2026 +                objHandles[i] = passHandle;
 26.2027 +            }
 26.2028 +            passHandle = oldHandle;
 26.2029 +        }
 26.2030 +
 26.2031 +        /**
 26.2032 +         * Returns offset of field with given name and type.  A specified type
 26.2033 +         * of null matches all types, Object.class matches all non-primitive
 26.2034 +         * types, and any other non-null type matches assignable types only.
 26.2035 +         * If no matching field is found in the (incoming) class
 26.2036 +         * descriptor but a matching field is present in the associated local
 26.2037 +         * class descriptor, returns -1.  Throws IllegalArgumentException if
 26.2038 +         * neither incoming nor local class descriptor contains a match.
 26.2039 +         */
 26.2040 +        private int getFieldOffset(String name, Class type) {
 26.2041 +            ObjectStreamField field = desc.getField(name, type);
 26.2042 +            if (field != null) {
 26.2043 +                return field.getOffset();
 26.2044 +            } else if (desc.getLocalDesc().getField(name, type) != null) {
 26.2045 +                return -1;
 26.2046 +            } else {
 26.2047 +                throw new IllegalArgumentException("no such field " + name +
 26.2048 +                                                   " with type " + type);
 26.2049 +            }
 26.2050 +        }
 26.2051 +    }
 26.2052 +
 26.2053 +    /**
 26.2054 +     * Prioritized list of callbacks to be performed once object graph has been
 26.2055 +     * completely deserialized.
 26.2056 +     */
 26.2057 +    private static class ValidationList {
 26.2058 +
 26.2059 +
 26.2060 +        /**
 26.2061 +         * Creates new (empty) ValidationList.
 26.2062 +         */
 26.2063 +        ValidationList() {
 26.2064 +        }
 26.2065 +
 26.2066 +        /**
 26.2067 +         * Registers callback.  Throws InvalidObjectException if callback
 26.2068 +         * object is null.
 26.2069 +         */
 26.2070 +        void register(ObjectInputValidation obj, int priority)
 26.2071 +            throws InvalidObjectException
 26.2072 +        {
 26.2073 +            if (obj == null) {
 26.2074 +                throw new InvalidObjectException("null callback");
 26.2075 +            }
 26.2076 +            throw new InvalidObjectException("Does not work.");
 26.2077 +        }
 26.2078 +
 26.2079 +        /**
 26.2080 +         * Invokes all registered callbacks and clears the callback list.
 26.2081 +         * Callbacks with higher priorities are called first; those with equal
 26.2082 +         * priorities may be called in any order.  If any of the callbacks
 26.2083 +         * throws an InvalidObjectException, the callback process is terminated
 26.2084 +         * and the exception propagated upwards.
 26.2085 +         */
 26.2086 +        void doCallbacks() throws InvalidObjectException {
 26.2087 +        }
 26.2088 +
 26.2089 +        /**
 26.2090 +         * Resets the callback list to its initial (empty) state.
 26.2091 +         */
 26.2092 +        public void clear() {
 26.2093 +        }
 26.2094 +    }
 26.2095 +
 26.2096 +    /**
 26.2097 +     * Input stream supporting single-byte peek operations.
 26.2098 +     */
 26.2099 +    private static class PeekInputStream extends InputStream {
 26.2100 +
 26.2101 +        /** underlying stream */
 26.2102 +        private final InputStream in;
 26.2103 +        /** peeked byte */
 26.2104 +        private int peekb = -1;
 26.2105 +
 26.2106 +        /**
 26.2107 +         * Creates new PeekInputStream on top of given underlying stream.
 26.2108 +         */
 26.2109 +        PeekInputStream(InputStream in) {
 26.2110 +            this.in = in;
 26.2111 +        }
 26.2112 +
 26.2113 +        /**
 26.2114 +         * Peeks at next byte value in stream.  Similar to read(), except
 26.2115 +         * that it does not consume the read value.
 26.2116 +         */
 26.2117 +        int peek() throws IOException {
 26.2118 +            return (peekb >= 0) ? peekb : (peekb = in.read());
 26.2119 +        }
 26.2120 +
 26.2121 +        public int read() throws IOException {
 26.2122 +            if (peekb >= 0) {
 26.2123 +                int v = peekb;
 26.2124 +                peekb = -1;
 26.2125 +                return v;
 26.2126 +            } else {
 26.2127 +                return in.read();
 26.2128 +            }
 26.2129 +        }
 26.2130 +
 26.2131 +        public int read(byte[] b, int off, int len) throws IOException {
 26.2132 +            if (len == 0) {
 26.2133 +                return 0;
 26.2134 +            } else if (peekb < 0) {
 26.2135 +                return in.read(b, off, len);
 26.2136 +            } else {
 26.2137 +                b[off++] = (byte) peekb;
 26.2138 +                len--;
 26.2139 +                peekb = -1;
 26.2140 +                int n = in.read(b, off, len);
 26.2141 +                return (n >= 0) ? (n + 1) : 1;
 26.2142 +            }
 26.2143 +        }
 26.2144 +
 26.2145 +        void readFully(byte[] b, int off, int len) throws IOException {
 26.2146 +            int n = 0;
 26.2147 +            while (n < len) {
 26.2148 +                int count = read(b, off + n, len - n);
 26.2149 +                if (count < 0) {
 26.2150 +                    throw new EOFException();
 26.2151 +                }
 26.2152 +                n += count;
 26.2153 +            }
 26.2154 +        }
 26.2155 +
 26.2156 +        public long skip(long n) throws IOException {
 26.2157 +            if (n <= 0) {
 26.2158 +                return 0;
 26.2159 +            }
 26.2160 +            int skipped = 0;
 26.2161 +            if (peekb >= 0) {
 26.2162 +                peekb = -1;
 26.2163 +                skipped++;
 26.2164 +                n--;
 26.2165 +            }
 26.2166 +            return skipped + skip(n);
 26.2167 +        }
 26.2168 +
 26.2169 +        public int available() throws IOException {
 26.2170 +            return in.available() + ((peekb >= 0) ? 1 : 0);
 26.2171 +        }
 26.2172 +
 26.2173 +        public void close() throws IOException {
 26.2174 +            in.close();
 26.2175 +        }
 26.2176 +    }
 26.2177 +
 26.2178 +    /**
 26.2179 +     * Input stream with two modes: in default mode, inputs data written in the
 26.2180 +     * same format as DataOutputStream; in "block data" mode, inputs data
 26.2181 +     * bracketed by block data markers (see object serialization specification
 26.2182 +     * for details).  Buffering depends on block data mode: when in default
 26.2183 +     * mode, no data is buffered in advance; when in block data mode, all data
 26.2184 +     * for the current data block is read in at once (and buffered).
 26.2185 +     */
 26.2186 +    private class BlockDataInputStream
 26.2187 +        extends InputStream implements DataInput
 26.2188 +    {
 26.2189 +        /** maximum data block length */
 26.2190 +        private static final int MAX_BLOCK_SIZE = 1024;
 26.2191 +        /** maximum data block header length */
 26.2192 +        private static final int MAX_HEADER_SIZE = 5;
 26.2193 +        /** (tunable) length of char buffer (for reading strings) */
 26.2194 +        private static final int CHAR_BUF_SIZE = 256;
 26.2195 +        /** readBlockHeader() return value indicating header read may block */
 26.2196 +        private static final int HEADER_BLOCKED = -2;
 26.2197 +
 26.2198 +        /** buffer for reading general/block data */
 26.2199 +        private final byte[] buf = new byte[MAX_BLOCK_SIZE];
 26.2200 +        /** buffer for reading block data headers */
 26.2201 +        private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
 26.2202 +        /** char buffer for fast string reads */
 26.2203 +        private final char[] cbuf = new char[CHAR_BUF_SIZE];
 26.2204 +
 26.2205 +        /** block data mode */
 26.2206 +        private boolean blkmode = false;
 26.2207 +
 26.2208 +        // block data state fields; values meaningful only when blkmode true
 26.2209 +        /** current offset into buf */
 26.2210 +        private int pos = 0;
 26.2211 +        /** end offset of valid data in buf, or -1 if no more block data */
 26.2212 +        private int end = -1;
 26.2213 +        /** number of bytes in current block yet to be read from stream */
 26.2214 +        private int unread = 0;
 26.2215 +
 26.2216 +        /** underlying stream (wrapped in peekable filter stream) */
 26.2217 +        private final PeekInputStream in;
 26.2218 +        /** loopback stream (for data reads that span data blocks) */
 26.2219 +        private final DataInputStream din;
 26.2220 +
 26.2221 +        /**
 26.2222 +         * Creates new BlockDataInputStream on top of given underlying stream.
 26.2223 +         * Block data mode is turned off by default.
 26.2224 +         */
 26.2225 +        BlockDataInputStream(InputStream in) {
 26.2226 +            this.in = new PeekInputStream(in);
 26.2227 +            din = new DataInputStream(this);
 26.2228 +        }
 26.2229 +
 26.2230 +        /**
 26.2231 +         * Sets block data mode to the given mode (true == on, false == off)
 26.2232 +         * and returns the previous mode value.  If the new mode is the same as
 26.2233 +         * the old mode, no action is taken.  Throws IllegalStateException if
 26.2234 +         * block data mode is being switched from on to off while unconsumed
 26.2235 +         * block data is still present in the stream.
 26.2236 +         */
 26.2237 +        boolean setBlockDataMode(boolean newmode) throws IOException {
 26.2238 +            if (blkmode == newmode) {
 26.2239 +                return blkmode;
 26.2240 +            }
 26.2241 +            if (newmode) {
 26.2242 +                pos = 0;
 26.2243 +                end = 0;
 26.2244 +                unread = 0;
 26.2245 +            } else if (pos < end) {
 26.2246 +                throw new IllegalStateException("unread block data");
 26.2247 +            }
 26.2248 +            blkmode = newmode;
 26.2249 +            return !blkmode;
 26.2250 +        }
 26.2251 +
 26.2252 +        /**
 26.2253 +         * Returns true if the stream is currently in block data mode, false
 26.2254 +         * otherwise.
 26.2255 +         */
 26.2256 +        boolean getBlockDataMode() {
 26.2257 +            return blkmode;
 26.2258 +        }
 26.2259 +
 26.2260 +        /**
 26.2261 +         * If in block data mode, skips to the end of the current group of data
 26.2262 +         * blocks (but does not unset block data mode).  If not in block data
 26.2263 +         * mode, throws an IllegalStateException.
 26.2264 +         */
 26.2265 +        void skipBlockData() throws IOException {
 26.2266 +            if (!blkmode) {
 26.2267 +                throw new IllegalStateException("not in block data mode");
 26.2268 +            }
 26.2269 +            while (end >= 0) {
 26.2270 +                refill();
 26.2271 +            }
 26.2272 +        }
 26.2273 +
 26.2274 +        /**
 26.2275 +         * Attempts to read in the next block data header (if any).  If
 26.2276 +         * canBlock is false and a full header cannot be read without possibly
 26.2277 +         * blocking, returns HEADER_BLOCKED, else if the next element in the
 26.2278 +         * stream is a block data header, returns the block data length
 26.2279 +         * specified by the header, else returns -1.
 26.2280 +         */
 26.2281 +        private int readBlockHeader(boolean canBlock) throws IOException {
 26.2282 +            if (defaultDataEnd) {
 26.2283 +                /*
 26.2284 +                 * Fix for 4360508: stream is currently at the end of a field
 26.2285 +                 * value block written via default serialization; since there
 26.2286 +                 * is no terminating TC_ENDBLOCKDATA tag, simulate
 26.2287 +                 * end-of-custom-data behavior explicitly.
 26.2288 +                 */
 26.2289 +                return -1;
 26.2290 +            }
 26.2291 +            try {
 26.2292 +                for (;;) {
 26.2293 +                    int avail = canBlock ? Integer.MAX_VALUE : in.available();
 26.2294 +                    if (avail == 0) {
 26.2295 +                        return HEADER_BLOCKED;
 26.2296 +                    }
 26.2297 +
 26.2298 +                    int tc = in.peek();
 26.2299 +                    switch (tc) {
 26.2300 +                        case TC_BLOCKDATA:
 26.2301 +                            if (avail < 2) {
 26.2302 +                                return HEADER_BLOCKED;
 26.2303 +                            }
 26.2304 +                            in.readFully(hbuf, 0, 2);
 26.2305 +                            return hbuf[1] & 0xFF;
 26.2306 +
 26.2307 +                        case TC_BLOCKDATALONG:
 26.2308 +                            if (avail < 5) {
 26.2309 +                                return HEADER_BLOCKED;
 26.2310 +                            }
 26.2311 +                            in.readFully(hbuf, 0, 5);
 26.2312 +                            int len = Bits.getInt(hbuf, 1);
 26.2313 +                            if (len < 0) {
 26.2314 +                                throw new StreamCorruptedException(
 26.2315 +                                    "illegal block data header length: " +
 26.2316 +                                    len);
 26.2317 +                            }
 26.2318 +                            return len;
 26.2319 +
 26.2320 +                        /*
 26.2321 +                         * TC_RESETs may occur in between data blocks.
 26.2322 +                         * Unfortunately, this case must be parsed at a lower
 26.2323 +                         * level than other typecodes, since primitive data
 26.2324 +                         * reads may span data blocks separated by a TC_RESET.
 26.2325 +                         */
 26.2326 +                        case TC_RESET:
 26.2327 +                            in.read();
 26.2328 +                            handleReset();
 26.2329 +                            break;
 26.2330 +
 26.2331 +                        default:
 26.2332 +                            if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) {
 26.2333 +                                throw new StreamCorruptedException(
 26.2334 +                                    String.format("invalid type code: %02X",
 26.2335 +                                    tc));
 26.2336 +                            }
 26.2337 +                            return -1;
 26.2338 +                    }
 26.2339 +                }
 26.2340 +            } catch (EOFException ex) {
 26.2341 +                throw new StreamCorruptedException(
 26.2342 +                    "unexpected EOF while reading block data header");
 26.2343 +            }
 26.2344 +        }
 26.2345 +
 26.2346 +        /**
 26.2347 +         * Refills internal buffer buf with block data.  Any data in buf at the
 26.2348 +         * time of the call is considered consumed.  Sets the pos, end, and
 26.2349 +         * unread fields to reflect the new amount of available block data; if
 26.2350 +         * the next element in the stream is not a data block, sets pos and
 26.2351 +         * unread to 0 and end to -1.
 26.2352 +         */
 26.2353 +        private void refill() throws IOException {
 26.2354 +            try {
 26.2355 +                do {
 26.2356 +                    pos = 0;
 26.2357 +                    if (unread > 0) {
 26.2358 +                        int n =
 26.2359 +                            in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE));
 26.2360 +                        if (n >= 0) {
 26.2361 +                            end = n;
 26.2362 +                            unread -= n;
 26.2363 +                        } else {
 26.2364 +                            throw new StreamCorruptedException(
 26.2365 +                                "unexpected EOF in middle of data block");
 26.2366 +                        }
 26.2367 +                    } else {
 26.2368 +                        int n = readBlockHeader(true);
 26.2369 +                        if (n >= 0) {
 26.2370 +                            end = 0;
 26.2371 +                            unread = n;
 26.2372 +                        } else {
 26.2373 +                            end = -1;
 26.2374 +                            unread = 0;
 26.2375 +                        }
 26.2376 +                    }
 26.2377 +                } while (pos == end);
 26.2378 +            } catch (IOException ex) {
 26.2379 +                pos = 0;
 26.2380 +                end = -1;
 26.2381 +                unread = 0;
 26.2382 +                throw ex;
 26.2383 +            }
 26.2384 +        }
 26.2385 +
 26.2386 +        /**
 26.2387 +         * If in block data mode, returns the number of unconsumed bytes
 26.2388 +         * remaining in the current data block.  If not in block data mode,
 26.2389 +         * throws an IllegalStateException.
 26.2390 +         */
 26.2391 +        int currentBlockRemaining() {
 26.2392 +            if (blkmode) {
 26.2393 +                return (end >= 0) ? (end - pos) + unread : 0;
 26.2394 +            } else {
 26.2395 +                throw new IllegalStateException();
 26.2396 +            }
 26.2397 +        }
 26.2398 +
 26.2399 +        /**
 26.2400 +         * Peeks at (but does not consume) and returns the next byte value in
 26.2401 +         * the stream, or -1 if the end of the stream/block data (if in block
 26.2402 +         * data mode) has been reached.
 26.2403 +         */
 26.2404 +        int peek() throws IOException {
 26.2405 +            if (blkmode) {
 26.2406 +                if (pos == end) {
 26.2407 +                    refill();
 26.2408 +                }
 26.2409 +                return (end >= 0) ? (buf[pos] & 0xFF) : -1;
 26.2410 +            } else {
 26.2411 +                return in.peek();
 26.2412 +            }
 26.2413 +        }
 26.2414 +
 26.2415 +        /**
 26.2416 +         * Peeks at (but does not consume) and returns the next byte value in
 26.2417 +         * the stream, or throws EOFException if end of stream/block data has
 26.2418 +         * been reached.
 26.2419 +         */
 26.2420 +        byte peekByte() throws IOException {
 26.2421 +            int val = peek();
 26.2422 +            if (val < 0) {
 26.2423 +                throw new EOFException();
 26.2424 +            }
 26.2425 +            return (byte) val;
 26.2426 +        }
 26.2427 +
 26.2428 +
 26.2429 +        /* ----------------- generic input stream methods ------------------ */
 26.2430 +        /*
 26.2431 +         * The following methods are equivalent to their counterparts in
 26.2432 +         * InputStream, except that they interpret data block boundaries and
 26.2433 +         * read the requested data from within data blocks when in block data
 26.2434 +         * mode.
 26.2435 +         */
 26.2436 +
 26.2437 +        public int read() throws IOException {
 26.2438 +            if (blkmode) {
 26.2439 +                if (pos == end) {
 26.2440 +                    refill();
 26.2441 +                }
 26.2442 +                return (end >= 0) ? (buf[pos++] & 0xFF) : -1;
 26.2443 +            } else {
 26.2444 +                return in.read();
 26.2445 +            }
 26.2446 +        }
 26.2447 +
 26.2448 +        public int read(byte[] b, int off, int len) throws IOException {
 26.2449 +            return read(b, off, len, false);
 26.2450 +        }
 26.2451 +
 26.2452 +        public long skip(long len) throws IOException {
 26.2453 +            long remain = len;
 26.2454 +            while (remain > 0) {
 26.2455 +                if (blkmode) {
 26.2456 +                    if (pos == end) {
 26.2457 +                        refill();
 26.2458 +                    }
 26.2459 +                    if (end < 0) {
 26.2460 +                        break;
 26.2461 +                    }
 26.2462 +                    int nread = (int) Math.min(remain, end - pos);
 26.2463 +                    remain -= nread;
 26.2464 +                    pos += nread;
 26.2465 +                } else {
 26.2466 +                    int nread = (int) Math.min(remain, MAX_BLOCK_SIZE);
 26.2467 +                    if ((nread = in.read(buf, 0, nread)) < 0) {
 26.2468 +                        break;
 26.2469 +                    }
 26.2470 +                    remain -= nread;
 26.2471 +                }
 26.2472 +            }
 26.2473 +            return len - remain;
 26.2474 +        }
 26.2475 +
 26.2476 +        public int available() throws IOException {
 26.2477 +            if (blkmode) {
 26.2478 +                if ((pos == end) && (unread == 0)) {
 26.2479 +                    int n;
 26.2480 +                    while ((n = readBlockHeader(false)) == 0) ;
 26.2481 +                    switch (n) {
 26.2482 +                        case HEADER_BLOCKED:
 26.2483 +                            break;
 26.2484 +
 26.2485 +                        case -1:
 26.2486 +                            pos = 0;
 26.2487 +                            end = -1;
 26.2488 +                            break;
 26.2489 +
 26.2490 +                        default:
 26.2491 +                            pos = 0;
 26.2492 +                            end = 0;
 26.2493 +                            unread = n;
 26.2494 +                            break;
 26.2495 +                    }
 26.2496 +                }
 26.2497 +                // avoid unnecessary call to in.available() if possible
 26.2498 +                int unreadAvail = (unread > 0) ?
 26.2499 +                    Math.min(in.available(), unread) : 0;
 26.2500 +                return (end >= 0) ? (end - pos) + unreadAvail : 0;
 26.2501 +            } else {
 26.2502 +                return in.available();
 26.2503 +            }
 26.2504 +        }
 26.2505 +
 26.2506 +        public void close() throws IOException {
 26.2507 +            if (blkmode) {
 26.2508 +                pos = 0;
 26.2509 +                end = -1;
 26.2510 +                unread = 0;
 26.2511 +            }
 26.2512 +            in.close();
 26.2513 +        }
 26.2514 +
 26.2515 +        /**
 26.2516 +         * Attempts to read len bytes into byte array b at offset off.  Returns
 26.2517 +         * the number of bytes read, or -1 if the end of stream/block data has
 26.2518 +         * been reached.  If copy is true, reads values into an intermediate
 26.2519 +         * buffer before copying them to b (to avoid exposing a reference to
 26.2520 +         * b).
 26.2521 +         */
 26.2522 +        int read(byte[] b, int off, int len, boolean copy) throws IOException {
 26.2523 +            if (len == 0) {
 26.2524 +                return 0;
 26.2525 +            } else if (blkmode) {
 26.2526 +                if (pos == end) {
 26.2527 +                    refill();
 26.2528 +                }
 26.2529 +                if (end < 0) {
 26.2530 +                    return -1;
 26.2531 +                }
 26.2532 +                int nread = Math.min(len, end - pos);
 26.2533 +                System.arraycopy(buf, pos, b, off, nread);
 26.2534 +                pos += nread;
 26.2535 +                return nread;
 26.2536 +            } else if (copy) {
 26.2537 +                int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE));
 26.2538 +                if (nread > 0) {
 26.2539 +                    System.arraycopy(buf, 0, b, off, nread);
 26.2540 +                }
 26.2541 +                return nread;
 26.2542 +            } else {
 26.2543 +                return in.read(b, off, len);
 26.2544 +            }
 26.2545 +        }
 26.2546 +
 26.2547 +        /* ----------------- primitive data input methods ------------------ */
 26.2548 +        /*
 26.2549 +         * The following methods are equivalent to their counterparts in
 26.2550 +         * DataInputStream, except that they interpret data block boundaries
 26.2551 +         * and read the requested data from within data blocks when in block
 26.2552 +         * data mode.
 26.2553 +         */
 26.2554 +
 26.2555 +        public void readFully(byte[] b) throws IOException {
 26.2556 +            readFully(b, 0, b.length, false);
 26.2557 +        }
 26.2558 +
 26.2559 +        public void readFully(byte[] b, int off, int len) throws IOException {
 26.2560 +            readFully(b, off, len, false);
 26.2561 +        }
 26.2562 +
 26.2563 +        public void readFully(byte[] b, int off, int len, boolean copy)
 26.2564 +            throws IOException
 26.2565 +        {
 26.2566 +            while (len > 0) {
 26.2567 +                int n = read(b, off, len, copy);
 26.2568 +                if (n < 0) {
 26.2569 +                    throw new EOFException();
 26.2570 +                }
 26.2571 +                off += n;
 26.2572 +                len -= n;
 26.2573 +            }
 26.2574 +        }
 26.2575 +
 26.2576 +        public int skipBytes(int n) throws IOException {
 26.2577 +            return din.skipBytes(n);
 26.2578 +        }
 26.2579 +
 26.2580 +        public boolean readBoolean() throws IOException {
 26.2581 +            int v = read();
 26.2582 +            if (v < 0) {
 26.2583 +                throw new EOFException();
 26.2584 +            }
 26.2585 +            return (v != 0);
 26.2586 +        }
 26.2587 +
 26.2588 +        public byte readByte() throws IOException {
 26.2589 +            int v = read();
 26.2590 +            if (v < 0) {
 26.2591 +                throw new EOFException();
 26.2592 +            }
 26.2593 +            return (byte) v;
 26.2594 +        }
 26.2595 +
 26.2596 +        public int readUnsignedByte() throws IOException {
 26.2597 +            int v = read();
 26.2598 +            if (v < 0) {
 26.2599 +                throw new EOFException();
 26.2600 +            }
 26.2601 +            return v;
 26.2602 +        }
 26.2603 +
 26.2604 +        public char readChar() throws IOException {
 26.2605 +            if (!blkmode) {
 26.2606 +                pos = 0;
 26.2607 +                in.readFully(buf, 0, 2);
 26.2608 +            } else if (end - pos < 2) {
 26.2609 +                return din.readChar();
 26.2610 +            }
 26.2611 +            char v = Bits.getChar(buf, pos);
 26.2612 +            pos += 2;
 26.2613 +            return v;
 26.2614 +        }
 26.2615 +
 26.2616 +        public short readShort() throws IOException {
 26.2617 +            if (!blkmode) {
 26.2618 +                pos = 0;
 26.2619 +                in.readFully(buf, 0, 2);
 26.2620 +            } else if (end - pos < 2) {
 26.2621 +                return din.readShort();
 26.2622 +            }
 26.2623 +            short v = Bits.getShort(buf, pos);
 26.2624 +            pos += 2;
 26.2625 +            return v;
 26.2626 +        }
 26.2627 +
 26.2628 +        public int readUnsignedShort() throws IOException {
 26.2629 +            if (!blkmode) {
 26.2630 +                pos = 0;
 26.2631 +                in.readFully(buf, 0, 2);
 26.2632 +            } else if (end - pos < 2) {
 26.2633 +                return din.readUnsignedShort();
 26.2634 +            }
 26.2635 +            int v = Bits.getShort(buf, pos) & 0xFFFF;
 26.2636 +            pos += 2;
 26.2637 +            return v;
 26.2638 +        }
 26.2639 +
 26.2640 +        public int readInt() throws IOException {
 26.2641 +            if (!blkmode) {
 26.2642 +                pos = 0;
 26.2643 +                in.readFully(buf, 0, 4);
 26.2644 +            } else if (end - pos < 4) {
 26.2645 +                return din.readInt();
 26.2646 +            }
 26.2647 +            int v = Bits.getInt(buf, pos);
 26.2648 +            pos += 4;
 26.2649 +            return v;
 26.2650 +        }
 26.2651 +
 26.2652 +        public float readFloat() throws IOException {
 26.2653 +            if (!blkmode) {
 26.2654 +                pos = 0;
 26.2655 +                in.readFully(buf, 0, 4);
 26.2656 +            } else if (end - pos < 4) {
 26.2657 +                return din.readFloat();
 26.2658 +            }
 26.2659 +            float v = Bits.getFloat(buf, pos);
 26.2660 +            pos += 4;
 26.2661 +            return v;
 26.2662 +        }
 26.2663 +
 26.2664 +        public long readLong() throws IOException {
 26.2665 +            if (!blkmode) {
 26.2666 +                pos = 0;
 26.2667 +                in.readFully(buf, 0, 8);
 26.2668 +            } else if (end - pos < 8) {
 26.2669 +                return din.readLong();
 26.2670 +            }
 26.2671 +            long v = Bits.getLong(buf, pos);
 26.2672 +            pos += 8;
 26.2673 +            return v;
 26.2674 +        }
 26.2675 +
 26.2676 +        public double readDouble() throws IOException {
 26.2677 +            if (!blkmode) {
 26.2678 +                pos = 0;
 26.2679 +                in.readFully(buf, 0, 8);
 26.2680 +            } else if (end - pos < 8) {
 26.2681 +                return din.readDouble();
 26.2682 +            }
 26.2683 +            double v = Bits.getDouble(buf, pos);
 26.2684 +            pos += 8;
 26.2685 +            return v;
 26.2686 +        }
 26.2687 +
 26.2688 +        public String readUTF() throws IOException {
 26.2689 +            return readUTFBody(readUnsignedShort());
 26.2690 +        }
 26.2691 +
 26.2692 +        public String readLine() throws IOException {
 26.2693 +            return din.readLine();      // deprecated, not worth optimizing
 26.2694 +        }
 26.2695 +
 26.2696 +        /* -------------- primitive data array input methods --------------- */
 26.2697 +        /*
 26.2698 +         * The following methods read in spans of primitive data values.
 26.2699 +         * Though equivalent to calling the corresponding primitive read
 26.2700 +         * methods repeatedly, these methods are optimized for reading groups
 26.2701 +         * of primitive data values more efficiently.
 26.2702 +         */
 26.2703 +
 26.2704 +        void readBooleans(boolean[] v, int off, int len) throws IOException {
 26.2705 +            int stop, endoff = off + len;
 26.2706 +            while (off < endoff) {
 26.2707 +                if (!blkmode) {
 26.2708 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE);
 26.2709 +                    in.readFully(buf, 0, span);
 26.2710 +                    stop = off + span;
 26.2711 +                    pos = 0;
 26.2712 +                } else if (end - pos < 1) {
 26.2713 +                    v[off++] = din.readBoolean();
 26.2714 +                    continue;
 26.2715 +                } else {
 26.2716 +                    stop = Math.min(endoff, off + end - pos);
 26.2717 +                }
 26.2718 +
 26.2719 +                while (off < stop) {
 26.2720 +                    v[off++] = Bits.getBoolean(buf, pos++);
 26.2721 +                }
 26.2722 +            }
 26.2723 +        }
 26.2724 +
 26.2725 +        void readChars(char[] v, int off, int len) throws IOException {
 26.2726 +            int stop, endoff = off + len;
 26.2727 +            while (off < endoff) {
 26.2728 +                if (!blkmode) {
 26.2729 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
 26.2730 +                    in.readFully(buf, 0, span << 1);
 26.2731 +                    stop = off + span;
 26.2732 +                    pos = 0;
 26.2733 +                } else if (end - pos < 2) {
 26.2734 +                    v[off++] = din.readChar();
 26.2735 +                    continue;
 26.2736 +                } else {
 26.2737 +                    stop = Math.min(endoff, off + ((end - pos) >> 1));
 26.2738 +                }
 26.2739 +
 26.2740 +                while (off < stop) {
 26.2741 +                    v[off++] = Bits.getChar(buf, pos);
 26.2742 +                    pos += 2;
 26.2743 +                }
 26.2744 +            }
 26.2745 +        }
 26.2746 +
 26.2747 +        void readShorts(short[] v, int off, int len) throws IOException {
 26.2748 +            int stop, endoff = off + len;
 26.2749 +            while (off < endoff) {
 26.2750 +                if (!blkmode) {
 26.2751 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
 26.2752 +                    in.readFully(buf, 0, span << 1);
 26.2753 +                    stop = off + span;
 26.2754 +                    pos = 0;
 26.2755 +                } else if (end - pos < 2) {
 26.2756 +                    v[off++] = din.readShort();
 26.2757 +                    continue;
 26.2758 +                } else {
 26.2759 +                    stop = Math.min(endoff, off + ((end - pos) >> 1));
 26.2760 +                }
 26.2761 +
 26.2762 +                while (off < stop) {
 26.2763 +                    v[off++] = Bits.getShort(buf, pos);
 26.2764 +                    pos += 2;
 26.2765 +                }
 26.2766 +            }
 26.2767 +        }
 26.2768 +
 26.2769 +        void readInts(int[] v, int off, int len) throws IOException {
 26.2770 +            int stop, endoff = off + len;
 26.2771 +            while (off < endoff) {
 26.2772 +                if (!blkmode) {
 26.2773 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
 26.2774 +                    in.readFully(buf, 0, span << 2);
 26.2775 +                    stop = off + span;
 26.2776 +                    pos = 0;
 26.2777 +                } else if (end - pos < 4) {
 26.2778 +                    v[off++] = din.readInt();
 26.2779 +                    continue;
 26.2780 +                } else {
 26.2781 +                    stop = Math.min(endoff, off + ((end - pos) >> 2));
 26.2782 +                }
 26.2783 +
 26.2784 +                while (off < stop) {
 26.2785 +                    v[off++] = Bits.getInt(buf, pos);
 26.2786 +                    pos += 4;
 26.2787 +                }
 26.2788 +            }
 26.2789 +        }
 26.2790 +
 26.2791 +        void readFloats(float[] v, int off, int len) throws IOException {
 26.2792 +            int span, endoff = off + len;
 26.2793 +            while (off < endoff) {
 26.2794 +                if (!blkmode) {
 26.2795 +                    span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
 26.2796 +                    in.readFully(buf, 0, span << 2);
 26.2797 +                    pos = 0;
 26.2798 +                } else if (end - pos < 4) {
 26.2799 +                    v[off++] = din.readFloat();
 26.2800 +                    continue;
 26.2801 +                } else {
 26.2802 +                    span = Math.min(endoff - off, ((end - pos) >> 2));
 26.2803 +                }
 26.2804 +
 26.2805 +                bytesToFloats(buf, pos, v, off, span);
 26.2806 +                off += span;
 26.2807 +                pos += span << 2;
 26.2808 +            }
 26.2809 +        }
 26.2810 +
 26.2811 +        void readLongs(long[] v, int off, int len) throws IOException {
 26.2812 +            int stop, endoff = off + len;
 26.2813 +            while (off < endoff) {
 26.2814 +                if (!blkmode) {
 26.2815 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
 26.2816 +                    in.readFully(buf, 0, span << 3);
 26.2817 +                    stop = off + span;
 26.2818 +                    pos = 0;
 26.2819 +                } else if (end - pos < 8) {
 26.2820 +                    v[off++] = din.readLong();
 26.2821 +                    continue;
 26.2822 +                } else {
 26.2823 +                    stop = Math.min(endoff, off + ((end - pos) >> 3));
 26.2824 +                }
 26.2825 +
 26.2826 +                while (off < stop) {
 26.2827 +                    v[off++] = Bits.getLong(buf, pos);
 26.2828 +                    pos += 8;
 26.2829 +                }
 26.2830 +            }
 26.2831 +        }
 26.2832 +
 26.2833 +        void readDoubles(double[] v, int off, int len) throws IOException {
 26.2834 +            int span, endoff = off + len;
 26.2835 +            while (off < endoff) {
 26.2836 +                if (!blkmode) {
 26.2837 +                    span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
 26.2838 +                    in.readFully(buf, 0, span << 3);
 26.2839 +                    pos = 0;
 26.2840 +                } else if (end - pos < 8) {
 26.2841 +                    v[off++] = din.readDouble();
 26.2842 +                    continue;
 26.2843 +                } else {
 26.2844 +                    span = Math.min(endoff - off, ((end - pos) >> 3));
 26.2845 +                }
 26.2846 +
 26.2847 +                bytesToDoubles(buf, pos, v, off, span);
 26.2848 +                off += span;
 26.2849 +                pos += span << 3;
 26.2850 +            }
 26.2851 +        }
 26.2852 +
 26.2853 +        /**
 26.2854 +         * Reads in string written in "long" UTF format.  "Long" UTF format is
 26.2855 +         * identical to standard UTF, except that it uses an 8 byte header
 26.2856 +         * (instead of the standard 2 bytes) to convey the UTF encoding length.
 26.2857 +         */
 26.2858 +        String readLongUTF() throws IOException {
 26.2859 +            return readUTFBody(readLong());
 26.2860 +        }
 26.2861 +
 26.2862 +        /**
 26.2863 +         * Reads in the "body" (i.e., the UTF representation minus the 2-byte
 26.2864 +         * or 8-byte length header) of a UTF encoding, which occupies the next
 26.2865 +         * utflen bytes.
 26.2866 +         */
 26.2867 +        private String readUTFBody(long utflen) throws IOException {
 26.2868 +            StringBuilder sbuf = new StringBuilder();
 26.2869 +            if (!blkmode) {
 26.2870 +                end = pos = 0;
 26.2871 +            }
 26.2872 +
 26.2873 +            while (utflen > 0) {
 26.2874 +                int avail = end - pos;
 26.2875 +                if (avail >= 3 || (long) avail == utflen) {
 26.2876 +                    utflen -= readUTFSpan(sbuf, utflen);
 26.2877 +                } else {
 26.2878 +                    if (blkmode) {
 26.2879 +                        // near block boundary, read one byte at a time
 26.2880 +                        utflen -= readUTFChar(sbuf, utflen);
 26.2881 +                    } else {
 26.2882 +                        // shift and refill buffer manually
 26.2883 +                        if (avail > 0) {
 26.2884 +                            System.arraycopy(buf, pos, buf, 0, avail);
 26.2885 +                        }
 26.2886 +                        pos = 0;
 26.2887 +                        end = (int) Math.min(MAX_BLOCK_SIZE, utflen);
 26.2888 +                        in.readFully(buf, avail, end - avail);
 26.2889 +                    }
 26.2890 +                }
 26.2891 +            }
 26.2892 +
 26.2893 +            return sbuf.toString();
 26.2894 +        }
 26.2895 +
 26.2896 +        /**
 26.2897 +         * Reads span of UTF-encoded characters out of internal buffer
 26.2898 +         * (starting at offset pos and ending at or before offset end),
 26.2899 +         * consuming no more than utflen bytes.  Appends read characters to
 26.2900 +         * sbuf.  Returns the number of bytes consumed.
 26.2901 +         */
 26.2902 +        private long readUTFSpan(StringBuilder sbuf, long utflen)
 26.2903 +            throws IOException
 26.2904 +        {
 26.2905 +            int cpos = 0;
 26.2906 +            int start = pos;
 26.2907 +            int avail = Math.min(end - pos, CHAR_BUF_SIZE);
 26.2908 +            // stop short of last char unless all of utf bytes in buffer
 26.2909 +            int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen);
 26.2910 +            boolean outOfBounds = false;
 26.2911 +
 26.2912 +            try {
 26.2913 +                while (pos < stop) {
 26.2914 +                    int b1, b2, b3;
 26.2915 +                    b1 = buf[pos++] & 0xFF;
 26.2916 +                    switch (b1 >> 4) {
 26.2917 +                        case 0:
 26.2918 +                        case 1:
 26.2919 +                        case 2:
 26.2920 +                        case 3:
 26.2921 +                        case 4:
 26.2922 +                        case 5:
 26.2923 +                        case 6:
 26.2924 +                        case 7:   // 1 byte format: 0xxxxxxx
 26.2925 +                            cbuf[cpos++] = (char) b1;
 26.2926 +                            break;
 26.2927 +
 26.2928 +                        case 12:
 26.2929 +                        case 13:  // 2 byte format: 110xxxxx 10xxxxxx
 26.2930 +                            b2 = buf[pos++];
 26.2931 +                            if ((b2 & 0xC0) != 0x80) {
 26.2932 +                                throw new UTFDataFormatException();
 26.2933 +                            }
 26.2934 +                            cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) |
 26.2935 +                                                   ((b2 & 0x3F) << 0));
 26.2936 +                            break;
 26.2937 +
 26.2938 +                        case 14:  // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
 26.2939 +                            b3 = buf[pos + 1];
 26.2940 +                            b2 = buf[pos + 0];
 26.2941 +                            pos += 2;
 26.2942 +                            if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
 26.2943 +                                throw new UTFDataFormatException();
 26.2944 +                            }
 26.2945 +                            cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) |
 26.2946 +                                                   ((b2 & 0x3F) << 6) |
 26.2947 +                                                   ((b3 & 0x3F) << 0));
 26.2948 +                            break;
 26.2949 +
 26.2950 +                        default:  // 10xx xxxx, 1111 xxxx
 26.2951 +                            throw new UTFDataFormatException();
 26.2952 +                    }
 26.2953 +                }
 26.2954 +            } catch (ArrayIndexOutOfBoundsException ex) {
 26.2955 +                outOfBounds = true;
 26.2956 +            } finally {
 26.2957 +                if (outOfBounds || (pos - start) > utflen) {
 26.2958 +                    /*
 26.2959 +                     * Fix for 4450867: if a malformed utf char causes the
 26.2960 +                     * conversion loop to scan past the expected end of the utf
 26.2961 +                     * string, only consume the expected number of utf bytes.
 26.2962 +                     */
 26.2963 +                    pos = start + (int) utflen;
 26.2964 +                    throw new UTFDataFormatException();
 26.2965 +                }
 26.2966 +            }
 26.2967 +
 26.2968 +            sbuf.append(cbuf, 0, cpos);
 26.2969 +            return pos - start;
 26.2970 +        }
 26.2971 +
 26.2972 +        /**
 26.2973 +         * Reads in single UTF-encoded character one byte at a time, appends
 26.2974 +         * the character to sbuf, and returns the number of bytes consumed.
 26.2975 +         * This method is used when reading in UTF strings written in block
 26.2976 +         * data mode to handle UTF-encoded characters which (potentially)
 26.2977 +         * straddle block-data boundaries.
 26.2978 +         */
 26.2979 +        private int readUTFChar(StringBuilder sbuf, long utflen)
 26.2980 +            throws IOException
 26.2981 +        {
 26.2982 +            int b1, b2, b3;
 26.2983 +            b1 = readByte() & 0xFF;
 26.2984 +            switch (b1 >> 4) {
 26.2985 +                case 0:
 26.2986 +                case 1:
 26.2987 +                case 2:
 26.2988 +                case 3:
 26.2989 +                case 4:
 26.2990 +                case 5:
 26.2991 +                case 6:
 26.2992 +                case 7:     // 1 byte format: 0xxxxxxx
 26.2993 +                    sbuf.append((char) b1);
 26.2994 +                    return 1;
 26.2995 +
 26.2996 +                case 12:
 26.2997 +                case 13:    // 2 byte format: 110xxxxx 10xxxxxx
 26.2998 +                    if (utflen < 2) {
 26.2999 +                        throw new UTFDataFormatException();
 26.3000 +                    }
 26.3001 +                    b2 = readByte();
 26.3002 +                    if ((b2 & 0xC0) != 0x80) {
 26.3003 +                        throw new UTFDataFormatException();
 26.3004 +                    }
 26.3005 +                    sbuf.append((char) (((b1 & 0x1F) << 6) |
 26.3006 +                                        ((b2 & 0x3F) << 0)));
 26.3007 +                    return 2;
 26.3008 +
 26.3009 +                case 14:    // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
 26.3010 +                    if (utflen < 3) {
 26.3011 +                        if (utflen == 2) {
 26.3012 +                            readByte();         // consume remaining byte
 26.3013 +                        }
 26.3014 +                        throw new UTFDataFormatException();
 26.3015 +                    }
 26.3016 +                    b2 = readByte();
 26.3017 +                    b3 = readByte();
 26.3018 +                    if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
 26.3019 +                        throw new UTFDataFormatException();
 26.3020 +                    }
 26.3021 +                    sbuf.append((char) (((b1 & 0x0F) << 12) |
 26.3022 +                                        ((b2 & 0x3F) << 6) |
 26.3023 +                                        ((b3 & 0x3F) << 0)));
 26.3024 +                    return 3;
 26.3025 +
 26.3026 +                default:   // 10xx xxxx, 1111 xxxx
 26.3027 +                    throw new UTFDataFormatException();
 26.3028 +            }
 26.3029 +        }
 26.3030 +    }
 26.3031 +
 26.3032 +    /**
 26.3033 +     * Unsynchronized table which tracks wire handle to object mappings, as
 26.3034 +     * well as ClassNotFoundExceptions associated with deserialized objects.
 26.3035 +     * This class implements an exception-propagation algorithm for
 26.3036 +     * determining which objects should have ClassNotFoundExceptions associated
 26.3037 +     * with them, taking into account cycles and discontinuities (e.g., skipped
 26.3038 +     * fields) in the object graph.
 26.3039 +     *
 26.3040 +     * <p>General use of the table is as follows: during deserialization, a
 26.3041 +     * given object is first assigned a handle by calling the assign method.
 26.3042 +     * This method leaves the assigned handle in an "open" state, wherein
 26.3043 +     * dependencies on the exception status of other handles can be registered
 26.3044 +     * by calling the markDependency method, or an exception can be directly
 26.3045 +     * associated with the handle by calling markException.  When a handle is
 26.3046 +     * tagged with an exception, the HandleTable assumes responsibility for
 26.3047 +     * propagating the exception to any other objects which depend
 26.3048 +     * (transitively) on the exception-tagged object.
 26.3049 +     *
 26.3050 +     * <p>Once all exception information/dependencies for the handle have been
 26.3051 +     * registered, the handle should be "closed" by calling the finish method
 26.3052 +     * on it.  The act of finishing a handle allows the exception propagation
 26.3053 +     * algorithm to aggressively prune dependency links, lessening the
 26.3054 +     * performance/memory impact of exception tracking.
 26.3055 +     *
 26.3056 +     * <p>Note that the exception propagation algorithm used depends on handles
 26.3057 +     * being assigned/finished in LIFO order; however, for simplicity as well
 26.3058 +     * as memory conservation, it does not enforce this constraint.
 26.3059 +     */
 26.3060 +    // REMIND: add full description of exception propagation algorithm?
 26.3061 +    private static class HandleTable {
 26.3062 +
 26.3063 +        /* status codes indicating whether object has associated exception */
 26.3064 +        private static final byte STATUS_OK = 1;
 26.3065 +        private static final byte STATUS_UNKNOWN = 2;
 26.3066 +        private static final byte STATUS_EXCEPTION = 3;
 26.3067 +
 26.3068 +        /** array mapping handle -> object status */
 26.3069 +        byte[] status;
 26.3070 +        /** array mapping handle -> object/exception (depending on status) */
 26.3071 +        Object[] entries;
 26.3072 +        /** array mapping handle -> list of dependent handles (if any) */
 26.3073 +        HandleList[] deps;
 26.3074 +        /** lowest unresolved dependency */
 26.3075 +        int lowDep = -1;
 26.3076 +        /** number of handles in table */
 26.3077 +        int size = 0;
 26.3078 +
 26.3079 +        /**
 26.3080 +         * Creates handle table with the given initial capacity.
 26.3081 +         */
 26.3082 +        HandleTable(int initialCapacity) {
 26.3083 +            status = new byte[initialCapacity];
 26.3084 +            entries = new Object[initialCapacity];
 26.3085 +            deps = new HandleList[initialCapacity];
 26.3086 +        }
 26.3087 +
 26.3088 +        /**
 26.3089 +         * Assigns next available handle to given object, and returns assigned
 26.3090 +         * handle.  Once object has been completely deserialized (and all
 26.3091 +         * dependencies on other objects identified), the handle should be
 26.3092 +         * "closed" by passing it to finish().
 26.3093 +         */
 26.3094 +        int assign(Object obj) {
 26.3095 +            if (size >= entries.length) {
 26.3096 +                grow();
 26.3097 +            }
 26.3098 +            status[size] = STATUS_UNKNOWN;
 26.3099 +            entries[size] = obj;
 26.3100 +            return size++;
 26.3101 +        }
 26.3102 +
 26.3103 +        /**
 26.3104 +         * Registers a dependency (in exception status) of one handle on
 26.3105 +         * another.  The dependent handle must be "open" (i.e., assigned, but
 26.3106 +         * not finished yet).  No action is taken if either dependent or target
 26.3107 +         * handle is NULL_HANDLE.
 26.3108 +         */
 26.3109 +        void markDependency(int dependent, int target) {
 26.3110 +            if (dependent == NULL_HANDLE || target == NULL_HANDLE) {
 26.3111 +                return;
 26.3112 +            }
 26.3113 +            switch (status[dependent]) {
 26.3114 +
 26.3115 +                case STATUS_UNKNOWN:
 26.3116 +                    switch (status[target]) {
 26.3117 +                        case STATUS_OK:
 26.3118 +                            // ignore dependencies on objs with no exception
 26.3119 +                            break;
 26.3120 +
 26.3121 +                        case STATUS_EXCEPTION:
 26.3122 +                            // eagerly propagate exception
 26.3123 +                            markException(dependent,
 26.3124 +                                (ClassNotFoundException) entries[target]);
 26.3125 +                            break;
 26.3126 +
 26.3127 +                        case STATUS_UNKNOWN:
 26.3128 +                            // add to dependency list of target
 26.3129 +                            if (deps[target] == null) {
 26.3130 +                                deps[target] = new HandleList();
 26.3131 +                            }
 26.3132 +                            deps[target].add(dependent);
 26.3133 +
 26.3134 +                            // remember lowest unresolved target seen
 26.3135 +                            if (lowDep < 0 || lowDep > target) {
 26.3136 +                                lowDep = target;
 26.3137 +                            }
 26.3138 +                            break;
 26.3139 +
 26.3140 +                        default:
 26.3141 +                            throw new InternalError();
 26.3142 +                    }
 26.3143 +                    break;
 26.3144 +
 26.3145 +                case STATUS_EXCEPTION:
 26.3146 +                    break;
 26.3147 +
 26.3148 +                default:
 26.3149 +                    throw new InternalError();
 26.3150 +            }
 26.3151 +        }
 26.3152 +
 26.3153 +        /**
 26.3154 +         * Associates a ClassNotFoundException (if one not already associated)
 26.3155 +         * with the currently active handle and propagates it to other
 26.3156 +         * referencing objects as appropriate.  The specified handle must be
 26.3157 +         * "open" (i.e., assigned, but not finished yet).
 26.3158 +         */
 26.3159 +        void markException(int handle, ClassNotFoundException ex) {
 26.3160 +            switch (status[handle]) {
 26.3161 +                case STATUS_UNKNOWN:
 26.3162 +                    status[handle] = STATUS_EXCEPTION;
 26.3163 +                    entries[handle] = ex;
 26.3164 +
 26.3165 +                    // propagate exception to dependents
 26.3166 +                    HandleList dlist = deps[handle];
 26.3167 +                    if (dlist != null) {
 26.3168 +                        int ndeps = dlist.size();
 26.3169 +                        for (int i = 0; i < ndeps; i++) {
 26.3170 +                            markException(dlist.get(i), ex);
 26.3171 +                        }
 26.3172 +                        deps[handle] = null;
 26.3173 +                    }
 26.3174 +                    break;
 26.3175 +
 26.3176 +                case STATUS_EXCEPTION:
 26.3177 +                    break;
 26.3178 +
 26.3179 +                default:
 26.3180 +                    throw new InternalError();
 26.3181 +            }
 26.3182 +        }
 26.3183 +
 26.3184 +        /**
 26.3185 +         * Marks given handle as finished, meaning that no new dependencies
 26.3186 +         * will be marked for handle.  Calls to the assign and finish methods
 26.3187 +         * must occur in LIFO order.
 26.3188 +         */
 26.3189 +        void finish(int handle) {
 26.3190 +            int end;
 26.3191 +            if (lowDep < 0) {
 26.3192 +                // no pending unknowns, only resolve current handle
 26.3193 +                end = handle + 1;
 26.3194 +            } else if (lowDep >= handle) {
 26.3195 +                // pending unknowns now clearable, resolve all upward handles
 26.3196 +                end = size;
 26.3197 +                lowDep = -1;
 26.3198 +            } else {
 26.3199 +                // unresolved backrefs present, can't resolve anything yet
 26.3200 +                return;
 26.3201 +            }
 26.3202 +
 26.3203 +            // change STATUS_UNKNOWN -> STATUS_OK in selected span of handles
 26.3204 +            for (int i = handle; i < end; i++) {
 26.3205 +                switch (status[i]) {
 26.3206 +                    case STATUS_UNKNOWN:
 26.3207 +                        status[i] = STATUS_OK;
 26.3208 +                        deps[i] = null;
 26.3209 +                        break;
 26.3210 +
 26.3211 +                    case STATUS_OK:
 26.3212 +                    case STATUS_EXCEPTION:
 26.3213 +                        break;
 26.3214 +
 26.3215 +                    default:
 26.3216 +                        throw new InternalError();
 26.3217 +                }
 26.3218 +            }
 26.3219 +        }
 26.3220 +
 26.3221 +        /**
 26.3222 +         * Assigns a new object to the given handle.  The object previously
 26.3223 +         * associated with the handle is forgotten.  This method has no effect
 26.3224 +         * if the given handle already has an exception associated with it.
 26.3225 +         * This method may be called at any time after the handle is assigned.
 26.3226 +         */
 26.3227 +        void setObject(int handle, Object obj) {
 26.3228 +            switch (status[handle]) {
 26.3229 +                case STATUS_UNKNOWN:
 26.3230 +                case STATUS_OK:
 26.3231 +                    entries[handle] = obj;
 26.3232 +                    break;
 26.3233 +
 26.3234 +                case STATUS_EXCEPTION:
 26.3235 +                    break;
 26.3236 +
 26.3237 +                default:
 26.3238 +                    throw new InternalError();
 26.3239 +            }
 26.3240 +        }
 26.3241 +
 26.3242 +        /**
 26.3243 +         * Looks up and returns object associated with the given handle.
 26.3244 +         * Returns null if the given handle is NULL_HANDLE, or if it has an
 26.3245 +         * associated ClassNotFoundException.
 26.3246 +         */
 26.3247 +        Object lookupObject(int handle) {
 26.3248 +            return (handle != NULL_HANDLE &&
 26.3249 +                    status[handle] != STATUS_EXCEPTION) ?
 26.3250 +                entries[handle] : null;
 26.3251 +        }
 26.3252 +
 26.3253 +        /**
 26.3254 +         * Looks up and returns ClassNotFoundException associated with the
 26.3255 +         * given handle.  Returns null if the given handle is NULL_HANDLE, or
 26.3256 +         * if there is no ClassNotFoundException associated with the handle.
 26.3257 +         */
 26.3258 +        ClassNotFoundException lookupException(int handle) {
 26.3259 +            return (handle != NULL_HANDLE &&
 26.3260 +                    status[handle] == STATUS_EXCEPTION) ?
 26.3261 +                (ClassNotFoundException) entries[handle] : null;
 26.3262 +        }
 26.3263 +
 26.3264 +        /**
 26.3265 +         * Resets table to its initial state.
 26.3266 +         */
 26.3267 +        void clear() {
 26.3268 +            Arrays.fill(status, 0, size, (byte) 0);
 26.3269 +            Arrays.fill(entries, 0, size, null);
 26.3270 +            Arrays.fill(deps, 0, size, null);
 26.3271 +            lowDep = -1;
 26.3272 +            size = 0;
 26.3273 +        }
 26.3274 +
 26.3275 +        /**
 26.3276 +         * Returns number of handles registered in table.
 26.3277 +         */
 26.3278 +        int size() {
 26.3279 +            return size;
 26.3280 +        }
 26.3281 +
 26.3282 +        /**
 26.3283 +         * Expands capacity of internal arrays.
 26.3284 +         */
 26.3285 +        private void grow() {
 26.3286 +            int newCapacity = (entries.length << 1) + 1;
 26.3287 +
 26.3288 +            byte[] newStatus = new byte[newCapacity];
 26.3289 +            Object[] newEntries = new Object[newCapacity];
 26.3290 +            HandleList[] newDeps = new HandleList[newCapacity];
 26.3291 +
 26.3292 +            System.arraycopy(status, 0, newStatus, 0, size);
 26.3293 +            System.arraycopy(entries, 0, newEntries, 0, size);
 26.3294 +            System.arraycopy(deps, 0, newDeps, 0, size);
 26.3295 +
 26.3296 +            status = newStatus;
 26.3297 +            entries = newEntries;
 26.3298 +            deps = newDeps;
 26.3299 +        }
 26.3300 +
 26.3301 +        /**
 26.3302 +         * Simple growable list of (integer) handles.
 26.3303 +         */
 26.3304 +        private static class HandleList {
 26.3305 +            private int[] list = new int[4];
 26.3306 +            private int size = 0;
 26.3307 +
 26.3308 +            public HandleList() {
 26.3309 +            }
 26.3310 +
 26.3311 +            public void add(int handle) {
 26.3312 +                if (size >= list.length) {
 26.3313 +                    int[] newList = new int[list.length << 1];
 26.3314 +                    System.arraycopy(list, 0, newList, 0, list.length);
 26.3315 +                    list = newList;
 26.3316 +                }
 26.3317 +                list[size++] = handle;
 26.3318 +            }
 26.3319 +
 26.3320 +            public int get(int index) {
 26.3321 +                if (index >= size) {
 26.3322 +                    throw new ArrayIndexOutOfBoundsException();
 26.3323 +                }
 26.3324 +                return list[index];
 26.3325 +            }
 26.3326 +
 26.3327 +            public int size() {
 26.3328 +                return size;
 26.3329 +            }
 26.3330 +        }
 26.3331 +    }
 26.3332 +
 26.3333 +    /**
 26.3334 +     * Method for cloning arrays in case of using unsharing reading
 26.3335 +     */
 26.3336 +    private static Object cloneArray(Object array) {
 26.3337 +        if (array instanceof Object[]) {
 26.3338 +            return ((Object[]) array).clone();
 26.3339 +        } else if (array instanceof boolean[]) {
 26.3340 +            return ((boolean[]) array).clone();
 26.3341 +        } else if (array instanceof byte[]) {
 26.3342 +            return ((byte[]) array).clone();
 26.3343 +        } else if (array instanceof char[]) {
 26.3344 +            return ((char[]) array).clone();
 26.3345 +        } else if (array instanceof double[]) {
 26.3346 +            return ((double[]) array).clone();
 26.3347 +        } else if (array instanceof float[]) {
 26.3348 +            return ((float[]) array).clone();
 26.3349 +        } else if (array instanceof int[]) {
 26.3350 +            return ((int[]) array).clone();
 26.3351 +        } else if (array instanceof long[]) {
 26.3352 +            return ((long[]) array).clone();
 26.3353 +        } else if (array instanceof short[]) {
 26.3354 +            return ((short[]) array).clone();
 26.3355 +        } else {
 26.3356 +            throw new AssertionError();
 26.3357 +        }
 26.3358 +    }
 26.3359 +
 26.3360 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/emul/compact/src/main/java/java/io/ObjectInputValidation.java	Tue Feb 05 17:04:22 2013 +0100
    27.3 @@ -0,0 +1,45 @@
    27.4 +/*
    27.5 + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
    27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.7 + *
    27.8 + * This code is free software; you can redistribute it and/or modify it
    27.9 + * under the terms of the GNU General Public License version 2 only, as
   27.10 + * published by the Free Software Foundation.  Oracle designates this
   27.11 + * particular file as subject to the "Classpath" exception as provided
   27.12 + * by Oracle in the LICENSE file that accompanied this code.
   27.13 + *
   27.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   27.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.17 + * version 2 for more details (a copy is included in the LICENSE file that
   27.18 + * accompanied this code).
   27.19 + *
   27.20 + * You should have received a copy of the GNU General Public License version
   27.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   27.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.23 + *
   27.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.25 + * or visit www.oracle.com if you need additional information or have any
   27.26 + * questions.
   27.27 + */
   27.28 +
   27.29 +package java.io;
   27.30 +
   27.31 +/**
   27.32 + * Callback interface to allow validation of objects within a graph.
   27.33 + * Allows an object to be called when a complete graph of objects has
   27.34 + * been deserialized.
   27.35 + *
   27.36 + * @author  unascribed
   27.37 + * @see     ObjectInputStream
   27.38 + * @see     ObjectInputStream#registerValidation(java.io.ObjectInputValidation, int)
   27.39 + * @since   JDK1.1
   27.40 + */
   27.41 +public interface ObjectInputValidation {
   27.42 +    /**
   27.43 +     * Validates the object.
   27.44 +     *
   27.45 +     * @exception InvalidObjectException If the object cannot validate itself.
   27.46 +     */
   27.47 +    public void validateObject() throws InvalidObjectException;
   27.48 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/emul/compact/src/main/java/java/io/ObjectOutput.java	Tue Feb 05 17:04:22 2013 +0100
    28.3 @@ -0,0 +1,90 @@
    28.4 +/*
    28.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    28.7 + *
    28.8 + * This code is free software; you can redistribute it and/or modify it
    28.9 + * under the terms of the GNU General Public License version 2 only, as
   28.10 + * published by the Free Software Foundation.  Oracle designates this
   28.11 + * particular file as subject to the "Classpath" exception as provided
   28.12 + * by Oracle in the LICENSE file that accompanied this code.
   28.13 + *
   28.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   28.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   28.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   28.17 + * version 2 for more details (a copy is included in the LICENSE file that
   28.18 + * accompanied this code).
   28.19 + *
   28.20 + * You should have received a copy of the GNU General Public License version
   28.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   28.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   28.23 + *
   28.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   28.25 + * or visit www.oracle.com if you need additional information or have any
   28.26 + * questions.
   28.27 + */
   28.28 +
   28.29 +package java.io;
   28.30 +
   28.31 +/**
   28.32 + * ObjectOutput extends the DataOutput interface to include writing of objects.
   28.33 + * DataOutput includes methods for output of primitive types, ObjectOutput
   28.34 + * extends that interface to include objects, arrays, and Strings.
   28.35 + *
   28.36 + * @author  unascribed
   28.37 + * @see java.io.InputStream
   28.38 + * @see java.io.ObjectOutputStream
   28.39 + * @see java.io.ObjectInputStream
   28.40 + * @since   JDK1.1
   28.41 + */
   28.42 +public interface ObjectOutput extends DataOutput, AutoCloseable {
   28.43 +    /**
   28.44 +     * Write an object to the underlying storage or stream.  The
   28.45 +     * class that implements this interface defines how the object is
   28.46 +     * written.
   28.47 +     *
   28.48 +     * @param obj the object to be written
   28.49 +     * @exception IOException Any of the usual Input/Output related exceptions.
   28.50 +     */
   28.51 +    public void writeObject(Object obj)
   28.52 +      throws IOException;
   28.53 +
   28.54 +    /**
   28.55 +     * Writes a byte. This method will block until the byte is actually
   28.56 +     * written.
   28.57 +     * @param b the byte
   28.58 +     * @exception IOException If an I/O error has occurred.
   28.59 +     */
   28.60 +    public void write(int b) throws IOException;
   28.61 +
   28.62 +    /**
   28.63 +     * Writes an array of bytes. This method will block until the bytes
   28.64 +     * are actually written.
   28.65 +     * @param b the data to be written
   28.66 +     * @exception IOException If an I/O error has occurred.
   28.67 +     */
   28.68 +    public void write(byte b[]) throws IOException;
   28.69 +
   28.70 +    /**
   28.71 +     * Writes a sub array of bytes.
   28.72 +     * @param b the data to be written
   28.73 +     * @param off       the start offset in the data
   28.74 +     * @param len       the number of bytes that are written
   28.75 +     * @exception IOException If an I/O error has occurred.
   28.76 +     */
   28.77 +    public void write(byte b[], int off, int len) throws IOException;
   28.78 +
   28.79 +    /**
   28.80 +     * Flushes the stream. This will write any buffered
   28.81 +     * output bytes.
   28.82 +     * @exception IOException If an I/O error has occurred.
   28.83 +     */
   28.84 +    public void flush() throws IOException;
   28.85 +
   28.86 +    /**
   28.87 +     * Closes the stream. This method must be called
   28.88 +     * to release any resources associated with the
   28.89 +     * stream.
   28.90 +     * @exception IOException If an I/O error has occurred.
   28.91 +     */
   28.92 +    public void close() throws IOException;
   28.93 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/emul/compact/src/main/java/java/io/ObjectOutputStream.java	Tue Feb 05 17:04:22 2013 +0100
    29.3 @@ -0,0 +1,2369 @@
    29.4 +/*
    29.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    29.7 + *
    29.8 + * This code is free software; you can redistribute it and/or modify it
    29.9 + * under the terms of the GNU General Public License version 2 only, as
   29.10 + * published by the Free Software Foundation.  Oracle designates this
   29.11 + * particular file as subject to the "Classpath" exception as provided
   29.12 + * by Oracle in the LICENSE file that accompanied this code.
   29.13 + *
   29.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   29.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   29.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   29.17 + * version 2 for more details (a copy is included in the LICENSE file that
   29.18 + * accompanied this code).
   29.19 + *
   29.20 + * You should have received a copy of the GNU General Public License version
   29.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   29.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   29.23 + *
   29.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   29.25 + * or visit www.oracle.com if you need additional information or have any
   29.26 + * questions.
   29.27 + */
   29.28 +
   29.29 +package java.io;
   29.30 +
   29.31 +import java.util.ArrayList;
   29.32 +import java.util.Arrays;
   29.33 +import java.util.List;
   29.34 +import org.apidesign.bck2brwsr.emul.lang.System;
   29.35 +
   29.36 +/**
   29.37 + * An ObjectOutputStream writes primitive data types and graphs of Java objects
   29.38 + * to an OutputStream.  The objects can be read (reconstituted) using an
   29.39 + * ObjectInputStream.  Persistent storage of objects can be accomplished by
   29.40 + * using a file for the stream.  If the stream is a network socket stream, the
   29.41 + * objects can be reconstituted on another host or in another process.
   29.42 + *
   29.43 + * <p>Only objects that support the java.io.Serializable interface can be
   29.44 + * written to streams.  The class of each serializable object is encoded
   29.45 + * including the class name and signature of the class, the values of the
   29.46 + * object's fields and arrays, and the closure of any other objects referenced
   29.47 + * from the initial objects.
   29.48 + *
   29.49 + * <p>The method writeObject is used to write an object to the stream.  Any
   29.50 + * object, including Strings and arrays, is written with writeObject. Multiple
   29.51 + * objects or primitives can be written to the stream.  The objects must be
   29.52 + * read back from the corresponding ObjectInputstream with the same types and
   29.53 + * in the same order as they were written.
   29.54 + *
   29.55 + * <p>Primitive data types can also be written to the stream using the
   29.56 + * appropriate methods from DataOutput. Strings can also be written using the
   29.57 + * writeUTF method.
   29.58 + *
   29.59 + * <p>The default serialization mechanism for an object writes the class of the
   29.60 + * object, the class signature, and the values of all non-transient and
   29.61 + * non-static fields.  References to other objects (except in transient or
   29.62 + * static fields) cause those objects to be written also. Multiple references
   29.63 + * to a single object are encoded using a reference sharing mechanism so that
   29.64 + * graphs of objects can be restored to the same shape as when the original was
   29.65 + * written.
   29.66 + *
   29.67 + * <p>For example to write an object that can be read by the example in
   29.68 + * ObjectInputStream:
   29.69 + * <br>
   29.70 + * <pre>
   29.71 + *      FileOutputStream fos = new FileOutputStream("t.tmp");
   29.72 + *      ObjectOutputStream oos = new ObjectOutputStream(fos);
   29.73 + *
   29.74 + *      oos.writeInt(12345);
   29.75 + *      oos.writeObject("Today");
   29.76 + *      oos.writeObject(new Date());
   29.77 + *
   29.78 + *      oos.close();
   29.79 + * </pre>
   29.80 + *
   29.81 + * <p>Classes that require special handling during the serialization and
   29.82 + * deserialization process must implement special methods with these exact
   29.83 + * signatures:
   29.84 + * <br>
   29.85 + * <pre>
   29.86 + * private void readObject(java.io.ObjectInputStream stream)
   29.87 + *     throws IOException, ClassNotFoundException;
   29.88 + * private void writeObject(java.io.ObjectOutputStream stream)
   29.89 + *     throws IOException
   29.90 + * private void readObjectNoData()
   29.91 + *     throws ObjectStreamException;
   29.92 + * </pre>
   29.93 + *
   29.94 + * <p>The writeObject method is responsible for writing the state of the object
   29.95 + * for its particular class so that the corresponding readObject method can
   29.96 + * restore it.  The method does not need to concern itself with the state
   29.97 + * belonging to the object's superclasses or subclasses.  State is saved by
   29.98 + * writing the individual fields to the ObjectOutputStream using the
   29.99 + * writeObject method or by using the methods for primitive data types
  29.100 + * supported by DataOutput.
  29.101 + *
  29.102 + * <p>Serialization does not write out the fields of any object that does not
  29.103 + * implement the java.io.Serializable interface.  Subclasses of Objects that
  29.104 + * are not serializable can be serializable. In this case the non-serializable
  29.105 + * class must have a no-arg constructor to allow its fields to be initialized.
  29.106 + * In this case it is the responsibility of the subclass to save and restore
  29.107 + * the state of the non-serializable class. It is frequently the case that the
  29.108 + * fields of that class are accessible (public, package, or protected) or that
  29.109 + * there are get and set methods that can be used to restore the state.
  29.110 + *
  29.111 + * <p>Serialization of an object can be prevented by implementing writeObject
  29.112 + * and readObject methods that throw the NotSerializableException.  The
  29.113 + * exception will be caught by the ObjectOutputStream and abort the
  29.114 + * serialization process.
  29.115 + *
  29.116 + * <p>Implementing the Externalizable interface allows the object to assume
  29.117 + * complete control over the contents and format of the object's serialized
  29.118 + * form.  The methods of the Externalizable interface, writeExternal and
  29.119 + * readExternal, are called to save and restore the objects state.  When
  29.120 + * implemented by a class they can write and read their own state using all of
  29.121 + * the methods of ObjectOutput and ObjectInput.  It is the responsibility of
  29.122 + * the objects to handle any versioning that occurs.
  29.123 + *
  29.124 + * <p>Enum constants are serialized differently than ordinary serializable or
  29.125 + * externalizable objects.  The serialized form of an enum constant consists
  29.126 + * solely of its name; field values of the constant are not transmitted.  To
  29.127 + * serialize an enum constant, ObjectOutputStream writes the string returned by
  29.128 + * the constant's name method.  Like other serializable or externalizable
  29.129 + * objects, enum constants can function as the targets of back references
  29.130 + * appearing subsequently in the serialization stream.  The process by which
  29.131 + * enum constants are serialized cannot be customized; any class-specific
  29.132 + * writeObject and writeReplace methods defined by enum types are ignored
  29.133 + * during serialization.  Similarly, any serialPersistentFields or
  29.134 + * serialVersionUID field declarations are also ignored--all enum types have a
  29.135 + * fixed serialVersionUID of 0L.
  29.136 + *
  29.137 + * <p>Primitive data, excluding serializable fields and externalizable data, is
  29.138 + * written to the ObjectOutputStream in block-data records. A block data record
  29.139 + * is composed of a header and data. The block data header consists of a marker
  29.140 + * and the number of bytes to follow the header.  Consecutive primitive data
  29.141 + * writes are merged into one block-data record.  The blocking factor used for
  29.142 + * a block-data record will be 1024 bytes.  Each block-data record will be
  29.143 + * filled up to 1024 bytes, or be written whenever there is a termination of
  29.144 + * block-data mode.  Calls to the ObjectOutputStream methods writeObject,
  29.145 + * defaultWriteObject and writeFields initially terminate any existing
  29.146 + * block-data record.
  29.147 + *
  29.148 + * @author      Mike Warres
  29.149 + * @author      Roger Riggs
  29.150 + * @see java.io.DataOutput
  29.151 + * @see java.io.ObjectInputStream
  29.152 + * @see java.io.Serializable
  29.153 + * @see java.io.Externalizable
  29.154 + * @see <a href="../../../platform/serialization/spec/output.html">Object Serialization Specification, Section 2, Object Output Classes</a>
  29.155 + * @since       JDK1.1
  29.156 + */
  29.157 +public class ObjectOutputStream
  29.158 +    extends OutputStream implements ObjectOutput, ObjectStreamConstants
  29.159 +{
  29.160 +    /** filter stream for handling block data conversion */
  29.161 +    private final BlockDataOutputStream bout;
  29.162 +    /** obj -> wire handle map */
  29.163 +    private final HandleTable handles;
  29.164 +    /** obj -> replacement obj map */
  29.165 +    private final ReplaceTable subs;
  29.166 +    /** stream protocol version */
  29.167 +    private int protocol = PROTOCOL_VERSION_2;
  29.168 +    /** recursion depth */
  29.169 +    private int depth;
  29.170 +
  29.171 +    /** buffer for writing primitive field values */
  29.172 +    private byte[] primVals;
  29.173 +
  29.174 +    /** if true, invoke writeObjectOverride() instead of writeObject() */
  29.175 +    private final boolean enableOverride;
  29.176 +    /** if true, invoke replaceObject() */
  29.177 +    private boolean enableReplace;
  29.178 +
  29.179 +    // values below valid only during upcalls to writeObject()/writeExternal()
  29.180 +    /**
  29.181 +     * Context during upcalls to class-defined writeObject methods; holds
  29.182 +     * object currently being serialized and descriptor for current class.
  29.183 +     * Null when not during writeObject upcall.
  29.184 +     */
  29.185 +    private Object curContext;
  29.186 +    /** current PutField object */
  29.187 +    private PutFieldImpl curPut;
  29.188 +
  29.189 +    /** custom storage for debug trace info */
  29.190 +    private final DebugTraceInfoStack debugInfoStack;
  29.191 +
  29.192 +    /**
  29.193 +     * value of "sun.io.serialization.extendedDebugInfo" property,
  29.194 +     * as true or false for extended information about exception's place
  29.195 +     */
  29.196 +    private static final boolean extendedDebugInfo = false;
  29.197 +
  29.198 +    /**
  29.199 +     * Creates an ObjectOutputStream that writes to the specified OutputStream.
  29.200 +     * This constructor writes the serialization stream header to the
  29.201 +     * underlying stream; callers may wish to flush the stream immediately to
  29.202 +     * ensure that constructors for receiving ObjectInputStreams will not block
  29.203 +     * when reading the header.
  29.204 +     *
  29.205 +     * <p>If a security manager is installed, this constructor will check for
  29.206 +     * the "enableSubclassImplementation" SerializablePermission when invoked
  29.207 +     * directly or indirectly by the constructor of a subclass which overrides
  29.208 +     * the ObjectOutputStream.putFields or ObjectOutputStream.writeUnshared
  29.209 +     * methods.
  29.210 +     *
  29.211 +     * @param   out output stream to write to
  29.212 +     * @throws  IOException if an I/O error occurs while writing stream header
  29.213 +     * @throws  SecurityException if untrusted subclass illegally overrides
  29.214 +     *          security-sensitive methods
  29.215 +     * @throws  NullPointerException if <code>out</code> is <code>null</code>
  29.216 +     * @since   1.4
  29.217 +     * @see     ObjectOutputStream#ObjectOutputStream()
  29.218 +     * @see     ObjectOutputStream#putFields()
  29.219 +     * @see     ObjectInputStream#ObjectInputStream(InputStream)
  29.220 +     */
  29.221 +    public ObjectOutputStream(OutputStream out) throws IOException {
  29.222 +        verifySubclass();
  29.223 +        bout = new BlockDataOutputStream(out);
  29.224 +        handles = new HandleTable(10, (float) 3.00);
  29.225 +        subs = new ReplaceTable(10, (float) 3.00);
  29.226 +        enableOverride = false;
  29.227 +        writeStreamHeader();
  29.228 +        bout.setBlockDataMode(true);
  29.229 +        if (extendedDebugInfo) {
  29.230 +            debugInfoStack = new DebugTraceInfoStack();
  29.231 +        } else {
  29.232 +            debugInfoStack = null;
  29.233 +        }
  29.234 +    }
  29.235 +
  29.236 +    /**
  29.237 +     * Provide a way for subclasses that are completely reimplementing
  29.238 +     * ObjectOutputStream to not have to allocate private data just used by
  29.239 +     * this implementation of ObjectOutputStream.
  29.240 +     *
  29.241 +     * <p>If there is a security manager installed, this method first calls the
  29.242 +     * security manager's <code>checkPermission</code> method with a
  29.243 +     * <code>SerializablePermission("enableSubclassImplementation")</code>
  29.244 +     * permission to ensure it's ok to enable subclassing.
  29.245 +     *
  29.246 +     * @throws  SecurityException if a security manager exists and its
  29.247 +     *          <code>checkPermission</code> method denies enabling
  29.248 +     *          subclassing.
  29.249 +     * @see SecurityManager#checkPermission
  29.250 +     * @see java.io.SerializablePermission
  29.251 +     */
  29.252 +    protected ObjectOutputStream() throws IOException, SecurityException {
  29.253 +        throw new SecurityException();
  29.254 +    }
  29.255 +
  29.256 +    /**
  29.257 +     * Specify stream protocol version to use when writing the stream.
  29.258 +     *
  29.259 +     * <p>This routine provides a hook to enable the current version of
  29.260 +     * Serialization to write in a format that is backwards compatible to a
  29.261 +     * previous version of the stream format.
  29.262 +     *
  29.263 +     * <p>Every effort will be made to avoid introducing additional
  29.264 +     * backwards incompatibilities; however, sometimes there is no
  29.265 +     * other alternative.
  29.266 +     *
  29.267 +     * @param   version use ProtocolVersion from java.io.ObjectStreamConstants.
  29.268 +     * @throws  IllegalStateException if called after any objects
  29.269 +     *          have been serialized.
  29.270 +     * @throws  IllegalArgumentException if invalid version is passed in.
  29.271 +     * @throws  IOException if I/O errors occur
  29.272 +     * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1
  29.273 +     * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_2
  29.274 +     * @since   1.2
  29.275 +     */
  29.276 +    public void useProtocolVersion(int version) throws IOException {
  29.277 +        if (handles.size() != 0) {
  29.278 +            // REMIND: implement better check for pristine stream?
  29.279 +            throw new IllegalStateException("stream non-empty");
  29.280 +        }
  29.281 +        switch (version) {
  29.282 +            case PROTOCOL_VERSION_1:
  29.283 +            case PROTOCOL_VERSION_2:
  29.284 +                protocol = version;
  29.285 +                break;
  29.286 +
  29.287 +            default:
  29.288 +                throw new IllegalArgumentException(
  29.289 +                    "unknown version: " + version);
  29.290 +        }
  29.291 +    }
  29.292 +
  29.293 +    /**
  29.294 +     * Write the specified object to the ObjectOutputStream.  The class of the
  29.295 +     * object, the signature of the class, and the values of the non-transient
  29.296 +     * and non-static fields of the class and all of its supertypes are
  29.297 +     * written.  Default serialization for a class can be overridden using the
  29.298 +     * writeObject and the readObject methods.  Objects referenced by this
  29.299 +     * object are written transitively so that a complete equivalent graph of
  29.300 +     * objects can be reconstructed by an ObjectInputStream.
  29.301 +     *
  29.302 +     * <p>Exceptions are thrown for problems with the OutputStream and for
  29.303 +     * classes that should not be serialized.  All exceptions are fatal to the
  29.304 +     * OutputStream, which is left in an indeterminate state, and it is up to
  29.305 +     * the caller to ignore or recover the stream state.
  29.306 +     *
  29.307 +     * @throws  InvalidClassException Something is wrong with a class used by
  29.308 +     *          serialization.
  29.309 +     * @throws  NotSerializableException Some object to be serialized does not
  29.310 +     *          implement the java.io.Serializable interface.
  29.311 +     * @throws  IOException Any exception thrown by the underlying
  29.312 +     *          OutputStream.
  29.313 +     */
  29.314 +    public final void writeObject(Object obj) throws IOException {
  29.315 +        if (enableOverride) {
  29.316 +            writeObjectOverride(obj);
  29.317 +            return;
  29.318 +        }
  29.319 +        try {
  29.320 +            writeObject0(obj, false);
  29.321 +        } catch (IOException ex) {
  29.322 +            if (depth == 0) {
  29.323 +                writeFatalException(ex);
  29.324 +            }
  29.325 +            throw ex;
  29.326 +        }
  29.327 +    }
  29.328 +
  29.329 +    /**
  29.330 +     * Method used by subclasses to override the default writeObject method.
  29.331 +     * This method is called by trusted subclasses of ObjectInputStream that
  29.332 +     * constructed ObjectInputStream using the protected no-arg constructor.
  29.333 +     * The subclass is expected to provide an override method with the modifier
  29.334 +     * "final".
  29.335 +     *
  29.336 +     * @param   obj object to be written to the underlying stream
  29.337 +     * @throws  IOException if there are I/O errors while writing to the
  29.338 +     *          underlying stream
  29.339 +     * @see #ObjectOutputStream()
  29.340 +     * @see #writeObject(Object)
  29.341 +     * @since 1.2
  29.342 +     */
  29.343 +    protected void writeObjectOverride(Object obj) throws IOException {
  29.344 +    }
  29.345 +
  29.346 +    /**
  29.347 +     * Writes an "unshared" object to the ObjectOutputStream.  This method is
  29.348 +     * identical to writeObject, except that it always writes the given object
  29.349 +     * as a new, unique object in the stream (as opposed to a back-reference
  29.350 +     * pointing to a previously serialized instance).  Specifically:
  29.351 +     * <ul>
  29.352 +     *   <li>An object written via writeUnshared is always serialized in the
  29.353 +     *       same manner as a newly appearing object (an object that has not
  29.354 +     *       been written to the stream yet), regardless of whether or not the
  29.355 +     *       object has been written previously.
  29.356 +     *
  29.357 +     *   <li>If writeObject is used to write an object that has been previously
  29.358 +     *       written with writeUnshared, the previous writeUnshared operation
  29.359 +     *       is treated as if it were a write of a separate object.  In other
  29.360 +     *       words, ObjectOutputStream will never generate back-references to
  29.361 +     *       object data written by calls to writeUnshared.
  29.362 +     * </ul>
  29.363 +     * While writing an object via writeUnshared does not in itself guarantee a
  29.364 +     * unique reference to the object when it is deserialized, it allows a
  29.365 +     * single object to be defined multiple times in a stream, so that multiple
  29.366 +     * calls to readUnshared by the receiver will not conflict.  Note that the
  29.367 +     * rules described above only apply to the base-level object written with
  29.368 +     * writeUnshared, and not to any transitively referenced sub-objects in the
  29.369 +     * object graph to be serialized.
  29.370 +     *
  29.371 +     * <p>ObjectOutputStream subclasses which override this method can only be
  29.372 +     * constructed in security contexts possessing the
  29.373 +     * "enableSubclassImplementation" SerializablePermission; any attempt to
  29.374 +     * instantiate such a subclass without this permission will cause a
  29.375 +     * SecurityException to be thrown.
  29.376 +     *
  29.377 +     * @param   obj object to write to stream
  29.378 +     * @throws  NotSerializableException if an object in the graph to be
  29.379 +     *          serialized does not implement the Serializable interface
  29.380 +     * @throws  InvalidClassException if a problem exists with the class of an
  29.381 +     *          object to be serialized
  29.382 +     * @throws  IOException if an I/O error occurs during serialization
  29.383 +     * @since 1.4
  29.384 +     */
  29.385 +    public void writeUnshared(Object obj) throws IOException {
  29.386 +        try {
  29.387 +            writeObject0(obj, true);
  29.388 +        } catch (IOException ex) {
  29.389 +            if (depth == 0) {
  29.390 +                writeFatalException(ex);
  29.391 +            }
  29.392 +            throw ex;
  29.393 +        }
  29.394 +    }
  29.395 +
  29.396 +    /**
  29.397 +     * Write the non-static and non-transient fields of the current class to
  29.398 +     * this stream.  This may only be called from the writeObject method of the
  29.399 +     * class being serialized. It will throw the NotActiveException if it is
  29.400 +     * called otherwise.
  29.401 +     *
  29.402 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.403 +     *          <code>OutputStream</code>
  29.404 +     */
  29.405 +    public void defaultWriteObject() throws IOException {
  29.406 +        if ( curContext == null ) {
  29.407 +            throw new NotActiveException("not in call to writeObject");
  29.408 +        }
  29.409 +        Object curObj = null; // curContext.getObj();
  29.410 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
  29.411 +        bout.setBlockDataMode(false);
  29.412 +        defaultWriteFields(curObj, curDesc);
  29.413 +        bout.setBlockDataMode(true);
  29.414 +    }
  29.415 +
  29.416 +    /**
  29.417 +     * Retrieve the object used to buffer persistent fields to be written to
  29.418 +     * the stream.  The fields will be written to the stream when writeFields
  29.419 +     * method is called.
  29.420 +     *
  29.421 +     * @return  an instance of the class Putfield that holds the serializable
  29.422 +     *          fields
  29.423 +     * @throws  IOException if I/O errors occur
  29.424 +     * @since 1.2
  29.425 +     */
  29.426 +    public ObjectOutputStream.PutField putFields() throws IOException {
  29.427 +        if (curPut == null) {
  29.428 +            if (curContext == null) {
  29.429 +                throw new NotActiveException("not in call to writeObject");
  29.430 +            }
  29.431 +            Object curObj = null; // curContext.getObj();
  29.432 +            ObjectStreamClass curDesc = null; // curContext.getDesc();
  29.433 +            curPut = new PutFieldImpl(curDesc);
  29.434 +        }
  29.435 +        return curPut;
  29.436 +    }
  29.437 +
  29.438 +    /**
  29.439 +     * Write the buffered fields to the stream.
  29.440 +     *
  29.441 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.442 +     *          stream
  29.443 +     * @throws  NotActiveException Called when a classes writeObject method was
  29.444 +     *          not called to write the state of the object.
  29.445 +     * @since 1.2
  29.446 +     */
  29.447 +    public void writeFields() throws IOException {
  29.448 +        if (curPut == null) {
  29.449 +            throw new NotActiveException("no current PutField object");
  29.450 +        }
  29.451 +        bout.setBlockDataMode(false);
  29.452 +        curPut.writeFields();
  29.453 +        bout.setBlockDataMode(true);
  29.454 +    }
  29.455 +
  29.456 +    /**
  29.457 +     * Reset will disregard the state of any objects already written to the
  29.458 +     * stream.  The state is reset to be the same as a new ObjectOutputStream.
  29.459 +     * The current point in the stream is marked as reset so the corresponding
  29.460 +     * ObjectInputStream will be reset at the same point.  Objects previously
  29.461 +     * written to the stream will not be refered to as already being in the
  29.462 +     * stream.  They will be written to the stream again.
  29.463 +     *
  29.464 +     * @throws  IOException if reset() is invoked while serializing an object.
  29.465 +     */
  29.466 +    public void reset() throws IOException {
  29.467 +        if (depth != 0) {
  29.468 +            throw new IOException("stream active");
  29.469 +        }
  29.470 +        bout.setBlockDataMode(false);
  29.471 +        bout.writeByte(TC_RESET);
  29.472 +        clear();
  29.473 +        bout.setBlockDataMode(true);
  29.474 +    }
  29.475 +
  29.476 +    /**
  29.477 +     * Subclasses may implement this method to allow class data to be stored in
  29.478 +     * the stream. By default this method does nothing.  The corresponding
  29.479 +     * method in ObjectInputStream is resolveClass.  This method is called
  29.480 +     * exactly once for each unique class in the stream.  The class name and
  29.481 +     * signature will have already been written to the stream.  This method may
  29.482 +     * make free use of the ObjectOutputStream to save any representation of
  29.483 +     * the class it deems suitable (for example, the bytes of the class file).
  29.484 +     * The resolveClass method in the corresponding subclass of
  29.485 +     * ObjectInputStream must read and use any data or objects written by
  29.486 +     * annotateClass.
  29.487 +     *
  29.488 +     * @param   cl the class to annotate custom data for
  29.489 +     * @throws  IOException Any exception thrown by the underlying
  29.490 +     *          OutputStream.
  29.491 +     */
  29.492 +    protected void annotateClass(Class<?> cl) throws IOException {
  29.493 +    }
  29.494 +
  29.495 +    /**
  29.496 +     * Subclasses may implement this method to store custom data in the stream
  29.497 +     * along with descriptors for dynamic proxy classes.
  29.498 +     *
  29.499 +     * <p>This method is called exactly once for each unique proxy class
  29.500 +     * descriptor in the stream.  The default implementation of this method in
  29.501 +     * <code>ObjectOutputStream</code> does nothing.
  29.502 +     *
  29.503 +     * <p>The corresponding method in <code>ObjectInputStream</code> is
  29.504 +     * <code>resolveProxyClass</code>.  For a given subclass of
  29.505 +     * <code>ObjectOutputStream</code> that overrides this method, the
  29.506 +     * <code>resolveProxyClass</code> method in the corresponding subclass of
  29.507 +     * <code>ObjectInputStream</code> must read any data or objects written by
  29.508 +     * <code>annotateProxyClass</code>.
  29.509 +     *
  29.510 +     * @param   cl the proxy class to annotate custom data for
  29.511 +     * @throws  IOException any exception thrown by the underlying
  29.512 +     *          <code>OutputStream</code>
  29.513 +     * @see ObjectInputStream#resolveProxyClass(String[])
  29.514 +     * @since   1.3
  29.515 +     */
  29.516 +    protected void annotateProxyClass(Class<?> cl) throws IOException {
  29.517 +    }
  29.518 +
  29.519 +    /**
  29.520 +     * This method will allow trusted subclasses of ObjectOutputStream to
  29.521 +     * substitute one object for another during serialization. Replacing
  29.522 +     * objects is disabled until enableReplaceObject is called. The
  29.523 +     * enableReplaceObject method checks that the stream requesting to do
  29.524 +     * replacement can be trusted.  The first occurrence of each object written
  29.525 +     * into the serialization stream is passed to replaceObject.  Subsequent
  29.526 +     * references to the object are replaced by the object returned by the
  29.527 +     * original call to replaceObject.  To ensure that the private state of
  29.528 +     * objects is not unintentionally exposed, only trusted streams may use
  29.529 +     * replaceObject.
  29.530 +     *
  29.531 +     * <p>The ObjectOutputStream.writeObject method takes a parameter of type
  29.532 +     * Object (as opposed to type Serializable) to allow for cases where
  29.533 +     * non-serializable objects are replaced by serializable ones.
  29.534 +     *
  29.535 +     * <p>When a subclass is replacing objects it must insure that either a
  29.536 +     * complementary substitution must be made during deserialization or that
  29.537 +     * the substituted object is compatible with every field where the
  29.538 +     * reference will be stored.  Objects whose type is not a subclass of the
  29.539 +     * type of the field or array element abort the serialization by raising an
  29.540 +     * exception and the object is not be stored.
  29.541 +     *
  29.542 +     * <p>This method is called only once when each object is first
  29.543 +     * encountered.  All subsequent references to the object will be redirected
  29.544 +     * to the new object. This method should return the object to be
  29.545 +     * substituted or the original object.
  29.546 +     *
  29.547 +     * <p>Null can be returned as the object to be substituted, but may cause