am 216438fc: (-s ours) am 83859891: am 3dc6a811: (-s ours) DO NOT MERGE. CTS test cleanup. Mark tests as KnownFailures and BrokenTests.
Merge commit '216438fc405d78069b1042cc21fc43dc85f860a9'
* commit '216438fc405d78069b1042cc21fc43dc85f860a9':
DO NOT MERGE. CTS test cleanup. Mark tests as KnownFailures and BrokenTests.
diff --git a/Android.mk b/Android.mk
index 7de73be..31db2f4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,163 +1,29 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# The core library is divided into modules. Each module has a separate Java
-# source directory, and some (hopefully eventually all) also have a directory
-# for tests. The two sections below define separate targets to build the
-# core and the associated tests.
-
-define all-core-java-files
-$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) && find */src/$(1)/java -name "*.java"))
-endef
-
-# Redirect ls stderr to /dev/null because the corresponding resources
-# directory doesn't always exist.
-define all-core-resource-dirs
-$(shell cd $(LOCAL_PATH) && ls -d */src/$(1)/{java,resources} 2> /dev/null)
-endef
-
-LOCAL_SRC_FILES := $(call all-core-java-files,main)
-LOCAL_JAVA_RESOURCE_DIRS := $(call all-core-resource-dirs,main)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_DX_FLAGS := --core-library
-
-LOCAL_NO_EMMA_INSTRUMENT := true
-LOCAL_NO_EMMA_COMPILE := true
-
-LOCAL_MODULE := core
-
-include $(BUILD_JAVA_LIBRARY)
-
-core-intermediates := ${intermediates}
-
-# Definitions to make the core-tests library.
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-core-java-files,test)
-LOCAL_JAVA_RESOURCE_DIRS := $(call all-core-resource-dirs,test)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core
-LOCAL_DX_FLAGS := --core-library
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE := core-tests
-
-include $(BUILD_JAVA_LIBRARY)
-
-# This one's tricky. One of our tests needs to have a
-# resource with a "#" in its name, but Perforce doesn't
-# allow us to submit such a file. So we create it here
-# on-the-fly.
-TMP_RESOURCE_DIR := $(OUT_DIR)/tmp/
-TMP_RESOURCE_FILE := org/apache/harmony/luni/tests/java/lang/test\#.properties
-
-$(TMP_RESOURCE_DIR)$(TMP_RESOURCE_FILE):
- @mkdir -p $(dir $@)
- @echo "Hello, world!" > $@
-
-$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args) -C $(TMP_RESOURCE_DIR) $(TMP_RESOURCE_FILE)
-$(LOCAL_INTERMEDIATE_TARGETS): $(TMP_RESOURCE_DIR)$(TMP_RESOURCE_FILE)
-
-# Definitions for building a version of the core-tests.jar
-# that is suitable for execution on the RI. This JAR would
-# be better located in $HOST_OUT_JAVA_LIBRARIES, but it is
-# not possible to refer to that from a shell script (the
-# variable is not exported from envsetup.sh). There is also
-# some trickery involved: we need to include some classes
-# that reside in core.jar, but since we cannot incldue the
-# whole core.jar in the RI classpath, we copy those classses
-# over to our new file.
-HOST_CORE_JAR := $(HOST_COMMON_OUT_ROOT)/core-tests.jar
-
-$(HOST_CORE_JAR): PRIVATE_LOCAL_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
-$(HOST_CORE_JAR): PRIVATE_CORE_INTERMEDIATES := $(core-intermediates)
-$(HOST_CORE_JAR): $(LOCAL_BUILT_MODULE)
- @rm -rf $(dir $<)/hostctsclasses
- $(call unzip-jar-files,$(dir $<)classes.jar,$(dir $<)hostctsclasses)
- @unzip -qx -o $(PRIVATE_CORE_INTERMEDIATES)/classes.jar dalvik/annotation/* -d $(dir $<)hostctsclasses
- @cp $< $@
- @jar uf $@ -C $(dir $<)hostctsclasses .
-
-$(LOCAL_INSTALLED_MODULE): $(HOST_CORE_JAR)
-
-$(LOCAL_INSTALLED_MODULE): run-core-tests
-
-# Definitions to copy the core-tests runner script.
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := run-core-tests
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE := run-core-tests
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := run-core-tests-on-ri
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE := run-core-tests-on-ri
-include $(BUILD_PREBUILT)
-
-# Build all of the native code, if any is present.
-
-include $(CLEAR_VARS)
-
-# Get the list of all native directories that contain sub.mk files.
-# We're using "sub.mk" to make it clear that these are not typical
-# android makefiles.
-define all-core-native-dirs
-$(patsubst %/sub.mk,%,$(shell cd $(LOCAL_PATH) && ls -d */src/$(1)/native/sub.mk 2> /dev/null))
-endef
-
-core_magic_local_target := ...//::default:://...
-core_local_path := $(LOCAL_PATH)
-
-# Include a submakefile, resolve its source file locations,
-# and stick them on core_src_files. The submakefiles are
-# free to append to LOCAL_C_INCLUDES, LOCAL_SHARED_LIBRARIES, etc.
+# Copyright (C) 2009 The Android Open Source Project
#
-# $(1): directory containing the makefile to include
-define include-core-native-dir
- LOCAL_SRC_FILES :=
- include $(LOCAL_PATH)/$(1)/sub.mk
- ifneq ($$(LOCAL_MODULE),$(core_magic_local_target))
- $$(error $(LOCAL_PATH)/$(1)/sub.mk should not include CLEAR_VARS \
- or define LOCAL_MODULE)
- endif
- ifneq ($$(LOCAL_PATH),$(core_local_path))
- $$(error $(LOCAL_PATH)/$(1)/sub.mk should not define LOCAL_PATH)
- endif
- core_src_files += $$(addprefix $(1)/,$$(LOCAL_SRC_FILES))
- LOCAL_SRC_FILES :=
-endef
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
-# Find any native directories containing sub.mk files.
-core_native_dirs := $(strip $(call all-core-native-dirs,main))
-ifeq ($(core_native_dirs),)
- $(error No native code defined for libcore)
-endif
+LOCAL_PATH := $(call my-dir)
-# Set up the default state.
-LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
-LOCAL_MODULE := $(core_magic_local_target)
-core_src_files :=
-# Include the sub.mk files.
-$(foreach dir, \
- $(core_native_dirs), \
- $(eval $(call include-core-native-dir,$(dir))))
+#
+# Include the definitions to build the Java code.
+#
-# Define the rules.
-LOCAL_SRC_FILES := $(core_src_files)
-LOCAL_MODULE := libjavacore
-include $(BUILD_STATIC_LIBRARY)
+include $(LOCAL_PATH)/JavaLibrary.mk
-# Deal with keystores required for security. Note: The path to this file
-# is hardcoded in TrustManagerFactoryImpl.java.
-ALL_PREBUILT += $(TARGET_OUT)/etc/security/cacerts.bks
-$(TARGET_OUT)/etc/security/cacerts.bks : $(LOCAL_PATH)/security/src/main/files/cacerts.bks | $(ACP)
- $(transform-prebuilt-to-target)
+
+#
+# Include the definitions to build the native code.
+#
+
+include $(LOCAL_PATH)/NativeCode.mk
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
new file mode 100644
index 0000000..d1015f5
--- /dev/null
+++ b/JavaLibrary.mk
@@ -0,0 +1,184 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Definitions for building the Java library and associated tests.
+#
+
+#
+# Common definitions for host and target.
+#
+
+# The core library is divided into modules. Each module has a separate
+# Java source directory, and some (hopefully eventually all) also have
+# a directory for tests.
+
+define all-core-java-files
+$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) && find */src/$(1)/java -name "*.java"))
+endef
+
+# Redirect ls stderr to /dev/null because the corresponding resources
+# directories don't always exist.
+define all-core-resource-dirs
+$(shell cd $(LOCAL_PATH) && ls -d */src/$(1)/{java,resources} 2> /dev/null)
+endef
+
+# The core Java files and associated resources.
+core_src_files := $(call all-core-java-files,main)
+core_resource_dirs := $(call all-core-resource-dirs,main)
+
+# The test Java files and associated resources.
+test_src_files := $(call all-core-java-files,test)
+test_resource_dirs := $(call all-core-resource-dirs,test)
+
+
+#
+# Build for the target (device).
+#
+
+# Definitions to make the core library.
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(core_src_files)
+LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_DX_FLAGS := --core-library
+
+LOCAL_NO_EMMA_INSTRUMENT := true
+LOCAL_NO_EMMA_COMPILE := true
+
+LOCAL_MODULE := core
+
+include $(BUILD_JAVA_LIBRARY)
+
+core-intermediates := ${intermediates}
+
+
+# Definitions to make the core-tests library.
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(test_src_files)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core
+LOCAL_DX_FLAGS := --core-library
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests
+
+include $(BUILD_JAVA_LIBRARY)
+
+
+
+# This one's tricky. One of our tests needs to have a
+# resource with a "#" in its name, but Perforce doesn't
+# allow us to submit such a file. So we create it here
+# on-the-fly.
+TMP_RESOURCE_DIR := $(OUT_DIR)/tmp/
+TMP_RESOURCE_FILE := org/apache/harmony/luni/tests/java/lang/test\#.properties
+
+$(TMP_RESOURCE_DIR)$(TMP_RESOURCE_FILE):
+ @mkdir -p $(dir $@)
+ @echo "Hello, world!" > $@
+
+$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_EXTRA_JAR_ARGS := $(extra_jar_args) -C $(TMP_RESOURCE_DIR) $(TMP_RESOURCE_FILE)
+$(LOCAL_INTERMEDIATE_TARGETS): $(TMP_RESOURCE_DIR)$(TMP_RESOURCE_FILE)
+
+# Definitions for building a version of the core-tests.jar
+# that is suitable for execution on the RI. This JAR would
+# be better located in $HOST_OUT_JAVA_LIBRARIES, but it is
+# not possible to refer to that from a shell script (the
+# variable is not exported from envsetup.sh). There is also
+# some trickery involved: we need to include some classes
+# that reside in core.jar, but since we cannot incldue the
+# whole core.jar in the RI classpath, we copy those classses
+# over to our new file.
+HOST_CORE_JAR := $(HOST_COMMON_OUT_ROOT)/core-tests.jar
+
+$(HOST_CORE_JAR): PRIVATE_LOCAL_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
+$(HOST_CORE_JAR): PRIVATE_CORE_INTERMEDIATES := $(core-intermediates)
+$(HOST_CORE_JAR): $(LOCAL_BUILT_MODULE)
+ @rm -rf $(dir $<)/hostctsclasses
+ $(call unzip-jar-files,$(dir $<)classes.jar,$(dir $<)hostctsclasses)
+ @unzip -qx -o $(PRIVATE_CORE_INTERMEDIATES)/classes.jar dalvik/annotation/* -d $(dir $<)hostctsclasses
+ @cp $< $@
+ @jar uf $@ -C $(dir $<)hostctsclasses .
+
+$(LOCAL_INSTALLED_MODULE): $(HOST_CORE_JAR)
+
+$(LOCAL_INSTALLED_MODULE): run-core-tests
+
+# Definitions to copy the core-tests runner script.
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := run-core-tests
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := run-core-tests
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := run-core-tests-on-ri
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := run-core-tests-on-ri
+include $(BUILD_PREBUILT)
+
+
+#
+# Build for the host.
+#
+
+ifeq ($(WITH_HOST_DALVIK),true)
+
+ # Definitions to make the core library.
+
+ include $(CLEAR_VARS)
+
+ LOCAL_SRC_FILES := $(core_src_files)
+ LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
+
+ LOCAL_NO_STANDARD_LIBRARIES := true
+ LOCAL_DX_FLAGS := --core-library
+
+ LOCAL_NO_EMMA_INSTRUMENT := true
+ LOCAL_NO_EMMA_COMPILE := true
+
+ LOCAL_MODULE := core
+
+ include $(BUILD_HOST_JAVA_LIBRARY)
+
+
+ # Definitions to make the core-tests library.
+
+ include $(CLEAR_VARS)
+
+ LOCAL_SRC_FILES := $(test_src_files)
+ LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+
+ LOCAL_NO_STANDARD_LIBRARIES := true
+ LOCAL_JAVA_LIBRARIES := core
+ LOCAL_DX_FLAGS := --core-library
+
+ LOCAL_MODULE_TAGS := tests
+ LOCAL_MODULE := core-tests
+
+ include $(BUILD_HOST_JAVA_LIBRARY)
+
+endif
\ No newline at end of file
diff --git a/NativeCode.mk b/NativeCode.mk
new file mode 100644
index 0000000..0dfad3b
--- /dev/null
+++ b/NativeCode.mk
@@ -0,0 +1,121 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Definitions for building the native code needed for the core library.
+#
+
+#
+# Common definitions for host and target.
+#
+
+# Get the list of all native directories that contain sub.mk files.
+# We're using "sub.mk" to make it clear that these are not typical
+# android makefiles.
+define all-core-native-dirs
+$(patsubst %/sub.mk,%,$(shell cd $(LOCAL_PATH) && ls -d */src/$(1)/native/sub.mk 2> /dev/null))
+endef
+
+# These two definitions are used to help sanity check what's put in
+# sub.mk. See, the "error" directives immediately below.
+core_magic_local_target := ...//::default:://...
+core_local_path := $(LOCAL_PATH)
+
+# Include a submakefile, resolve its source file locations,
+# and stick them on core_src_files. The submakefiles are
+# free to append to LOCAL_SRC_FILES, LOCAL_C_INCLUDES,
+# LOCAL_SHARED_LIBRARIES, or LOCAL_STATIC_LIBRARIES, but nothing
+# else. All other LOCAL_* variables will be ignored.
+#
+# $(1): directory containing the makefile to include
+define include-core-native-dir
+ LOCAL_SRC_FILES :=
+ include $(LOCAL_PATH)/$(1)/sub.mk
+ ifneq ($$(LOCAL_MODULE),$(core_magic_local_target))
+ $$(error $(LOCAL_PATH)/$(1)/sub.mk should not include CLEAR_VARS \
+ or define LOCAL_MODULE)
+ endif
+ ifneq ($$(LOCAL_PATH),$(core_local_path))
+ $$(error $(LOCAL_PATH)/$(1)/sub.mk should not define LOCAL_PATH)
+ endif
+ core_src_files += $$(addprefix $(1)/,$$(LOCAL_SRC_FILES))
+ LOCAL_SRC_FILES :=
+endef
+
+# Find any native directories containing sub.mk files.
+core_native_dirs := $(strip $(call all-core-native-dirs,main))
+ifeq ($(core_native_dirs),)
+ $(error No native code defined for libcore)
+endif
+
+# Set up the default state. Note: We use CLEAR_VARS here, even though
+# we aren't quite defining a new rule yet, to make sure that the
+# sub.mk files don't see anything stray from the last rule that was
+# set up.
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(core_magic_local_target)
+core_src_files :=
+
+# Include the sub.mk files.
+$(foreach dir, \
+ $(core_native_dirs), \
+ $(eval $(call include-core-native-dir,$(dir))))
+
+# Extract out the allowed LOCAL_* variables. Note: $(sort) also
+# removes duplicates.
+core_c_includes := $(sort $(LOCAL_C_INCLUDES) $(JNI_H_INCLUDE))
+core_shared_libraries := $(sort $(LOCAL_SHARED_LIBRARIES))
+core_static_libraries := $(sort $(LOCAL_STATIC_LIBRARIES))
+
+
+#
+# Build for the target (device).
+#
+
+include $(CLEAR_VARS)
+
+# Define the rules.
+LOCAL_SRC_FILES := $(core_src_files)
+LOCAL_C_INCLUDES := $(core_c_includes)
+LOCAL_SHARED_LIBRARIES := $(core_shared_libraries)
+LOCAL_STATIC_LIBRARIES := $(core_static_libraries)
+LOCAL_MODULE := libjavacore
+include $(BUILD_STATIC_LIBRARY)
+
+# Deal with keystores required for security. Note: The path to this file
+# is hardcoded in TrustManagerFactoryImpl.java.
+ALL_PREBUILT += $(TARGET_OUT)/etc/security/cacerts.bks
+$(TARGET_OUT)/etc/security/cacerts.bks : $(LOCAL_PATH)/security/src/main/files/cacerts.bks | $(ACP)
+ $(transform-prebuilt-to-target)
+
+
+#
+# Build for the host.
+#
+
+ifeq ($(WITH_HOST_DALVIK),true)
+
+ include $(CLEAR_VARS)
+
+ # Define the rules.
+ LOCAL_SRC_FILES := $(core_src_files)
+ LOCAL_C_INCLUDES := $(core_c_includes)
+ LOCAL_SHARED_LIBRARIES := $(core_shared_libraries)
+ LOCAL_STATIC_LIBRARIES := $(core_static_libraries)
+ LOCAL_MODULE := libjavacore-host
+ include $(BUILD_HOST_STATIC_LIBRARY)
+
+ # TODO: Figure out cacerts.bks for the host.
+
+endif
\ No newline at end of file
diff --git a/archive/src/main/java/java/util/jar/Attributes.java b/archive/src/main/java/java/util/jar/Attributes.java
index 4ee94df..159a0cd 100644
--- a/archive/src/main/java/java/util/jar/Attributes.java
+++ b/archive/src/main/java/java/util/jar/Attributes.java
@@ -437,7 +437,7 @@
try {
clone = (Attributes) super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
clone.map = (Map<Object, Object>) ((HashMap) map).clone();
return clone;
diff --git a/archive/src/main/java/java/util/zip/Deflater.java b/archive/src/main/java/java/util/zip/Deflater.java
index ee9c3ea..48ae479 100644
--- a/archive/src/main/java/java/util/zip/Deflater.java
+++ b/archive/src/main/java/java/util/zip/Deflater.java
@@ -17,9 +17,6 @@
package java.util.zip;
-// BEGIN android-changed
-// import org.apache.harmony.luni.platform.OSResourcesMonitor;
-// END android-changed
/**
* This class compresses data using the <i>DEFLATE</i> algorithm (see <a
@@ -149,8 +146,7 @@
throw new IllegalArgumentException();
}
compressLevel = level;
- streamHandle = createStreamWithMemoryEnsurance(compressLevel, strategy,
- noHeader);
+ streamHandle = createStream(compressLevel, strategy, noHeader);
}
/**
@@ -502,13 +498,5 @@
return getTotalOutImpl(streamHandle);
}
- private long createStreamWithMemoryEnsurance(int level, int strategy1,
- boolean noHeader1) {
- // BEGIN android-changed
- // OSResourcesMonitor.ensurePhysicalMemoryCapacity();
- // END android-changed
- return createStream(level, strategy1, noHeader1);
- }
-
private native long createStream(int level, int strategy1, boolean noHeader1);
}
diff --git a/archive/src/main/java/java/util/zip/ZipFile.java b/archive/src/main/java/java/util/zip/ZipFile.java
index 653b2c9..b5f3678 100644
--- a/archive/src/main/java/java/util/zip/ZipFile.java
+++ b/archive/src/main/java/java/util/zip/ZipFile.java
@@ -52,12 +52,12 @@
File fileToDeleteOnClose;
/**
- * Open zip file for read.
+ * Open ZIP file for read.
*/
public static final int OPEN_READ = 1;
/**
- * Delete zip file when closed.
+ * Delete ZIP file when closed.
*/
public static final int OPEN_DELETE = 4;
@@ -140,7 +140,7 @@
}
/**
- * Closes this ZIP file.
+ * Closes this ZIP file. This method is idempotent.
*
* @throws IOException
* if an IOException occurs.
@@ -166,23 +166,32 @@
}
}
+ private void checkNotClosed() {
+ if (mRaf == null) {
+ throw new IllegalStateException("Zip File closed.");
+ }
+ }
+
/**
* Returns an enumeration of the entries. The entries are listed in the
* order in which they appear in the ZIP archive.
*
* @return the enumeration of the entries.
+ * @throws IllegalStateException if this ZIP file has been closed.
*/
public Enumeration<? extends ZipEntry> entries() {
+ checkNotClosed();
+
return new Enumeration<ZipEntry>() {
private int i = 0;
public boolean hasMoreElements() {
- if (mRaf == null) throw new IllegalStateException("Zip File closed.");
+ checkNotClosed();
return i < mEntryList.size();
}
public ZipEntry nextElement() {
- if (mRaf == null) throw new IllegalStateException("Zip File closed.");
+ checkNotClosed();
if (i >= mEntryList.size())
throw new NoSuchElementException();
return (ZipEntry) mEntryList.get(i++);
@@ -197,8 +206,10 @@
* the name of the entry in the ZIP file.
* @return a {@code ZipEntry} or {@code null} if the entry name does not
* exist in the ZIP file.
+ * @throws IllegalStateException if this ZIP file has been closed.
*/
public ZipEntry getEntry(String entryName) {
+ checkNotClosed();
if (entryName != null) {
ZipEntry ze = mFastLookup.get(entryName);
if (ze == null) ze = mFastLookup.get(entryName + "/");
@@ -215,6 +226,7 @@
* @return an input stream of the data contained in the {@code ZipEntry}.
* @throws IOException
* if an {@code IOException} occurs.
+ * @throws IllegalStateException if this ZIP file has been closed.
*/
public InputStream getInputStream(ZipEntry entry) throws IOException {
/*
@@ -229,27 +241,25 @@
* Create a ZipInputStream at the right part of the file.
*/
RandomAccessFile raf = mRaf;
- if (raf != null) {
- synchronized (raf) {
- // Unfortunately we don't know the entry data's start position.
- // All we have is the position of the entry's local header.
- // At position 28 we find the length of the extra data.
- // In some cases this length differs from the one coming in
- // the central header!!!
- RAFStream rafstrm = new RAFStream(raf, entry.mLocalHeaderRelOffset + 28);
- int localExtraLenOrWhatever = ler.readShortLE(rafstrm);
- // Now we need to skip the name
- // and this "extra" data or whatever it is:
- rafstrm.skip(entry.nameLen + localExtraLenOrWhatever);
- rafstrm.mLength = rafstrm.mOffset + entry.compressedSize;
- if (entry.compressionMethod == ZipEntry.DEFLATED) {
- return new InflaterInputStream(rafstrm, new Inflater(true));
- } else {
- return rafstrm;
- }
+ synchronized (raf) {
+ // Unfortunately we don't know the entry data's start position.
+ // All we have is the position of the entry's local header.
+ // At position 28 we find the length of the extra data.
+ // In some cases this length differs from the one coming in
+ // the central header!!!
+ RAFStream rafstrm = new RAFStream(raf,
+ entry.mLocalHeaderRelOffset + 28);
+ int localExtraLenOrWhatever = ler.readShortLE(rafstrm);
+ // Now we need to skip the name
+ // and this "extra" data or whatever it is:
+ rafstrm.skip(entry.nameLen + localExtraLenOrWhatever);
+ rafstrm.mLength = rafstrm.mOffset + entry.compressedSize;
+ if (entry.compressionMethod == ZipEntry.DEFLATED) {
+ return new InflaterInputStream(rafstrm, new Inflater(true));
+ } else {
+ return rafstrm;
}
}
- throw new IllegalStateException("Zip File closed");
}
/**
@@ -265,8 +275,10 @@
* Returns the number of {@code ZipEntries} in this {@code ZipFile}.
*
* @return the number of entries in this file.
+ * @throws IllegalStateException if this ZIP file has been closed.
*/
public int size() {
+ checkNotClosed();
return mEntryList.size();
}
diff --git a/archive/src/main/native/java_util_zip_Adler32.c b/archive/src/main/native/java_util_zip_Adler32.c
index 1b02a11..0fcf549 100644
--- a/archive/src/main/native/java_util_zip_Adler32.c
+++ b/archive/src/main/native/java_util_zip_Adler32.c
@@ -25,16 +25,11 @@
jbyteArray buf, int off, int len,
jlong crc)
{
- jbyte *b;
- jboolean isCopy;
- jlong result;
-
- b = (*env)->GetPrimitiveArrayCritical (env, buf, &isCopy);
+ jbyte* b = (*env)->GetPrimitiveArrayCritical (env, buf, NULL);
if (b == NULL) {
- throwNewOutOfMemoryError(env, "");
return 0;
}
- result = (jlong) adler32 ((uLong) crc, (Bytef *) (b + off), (uInt) len);
+ jlong result = (jlong) adler32 ((uLong) crc, (Bytef *) (b + off), (uInt) len);
(*env)->ReleasePrimitiveArrayCritical (env, buf, b, JNI_ABORT);
return result;
diff --git a/archive/src/main/native/java_util_zip_CRC32.c b/archive/src/main/native/java_util_zip_CRC32.c
index cee25e5..fe50fca 100644
--- a/archive/src/main/native/java_util_zip_CRC32.c
+++ b/archive/src/main/native/java_util_zip_CRC32.c
@@ -25,15 +25,11 @@
jbyteArray buf, int off, int len,
jlong crc)
{
- jbyte *b;
- jlong result;
-
- b = ((*env)->GetPrimitiveArrayCritical (env, buf, 0));
+ jbyte* b = ((*env)->GetPrimitiveArrayCritical (env, buf, 0));
if (b == NULL) {
- throwNewOutOfMemoryError(env, "");
return -1;
}
- result = crc32 ((uLong) crc, (Bytef *) (b + off), (uInt) len);
+ jlong result = crc32 ((uLong) crc, (Bytef *) (b + off), (uInt) len);
((*env)->ReleasePrimitiveArrayCritical (env, buf, b, JNI_ABORT));
return result;
}
diff --git a/archive/src/main/native/java_util_zip_Deflater.c b/archive/src/main/native/java_util_zip_Deflater.c
index 2e0e268..af0bfcc 100644
--- a/archive/src/main/native/java_util_zip_Deflater.c
+++ b/archive/src/main/native/java_util_zip_Deflater.c
@@ -162,29 +162,19 @@
{
PORT_ACCESS_FROM_ENV (env);
- jbyte *in;
- JCLZipStream *stream;
-
- stream = (JCLZipStream *) ((IDATA) handle);
- if (stream->inaddr != NULL) /*Input has already been provided, free the old buffer */
+ JCLZipStream* stream = (JCLZipStream *) ((IDATA) handle);
+ if (stream->inaddr != NULL) {
+ /* Input has already been provided, free the old buffer. */
jclmem_free_memory (env, stream->inaddr);
+ }
stream->inaddr = jclmem_allocate_memory (env, len);
- if (stream->inaddr == NULL)
- {
- throwNewOutOfMemoryError (env, "");
- return;
- }
- in = ((*env)->GetPrimitiveArrayCritical (env, buf, 0));
- if (in == NULL) {
- throwNewOutOfMemoryError(env, "");
+ if (stream->inaddr == NULL) {
+ throwNewOutOfMemoryError (env, "");
return;
}
- memcpy (stream->inaddr, (in + off), len);
- ((*env)->ReleasePrimitiveArrayCritical (env, buf, in, JNI_ABORT));
+ (*env)->GetByteArrayRegion(env, buf, off, len, (jbyte*) stream->inaddr);
stream->stream->next_in = (Bytef *) stream->inaddr;
stream->stream->avail_in = len;
-
- return;
}
JNIEXPORT jint JNICALL
@@ -209,7 +199,6 @@
sout = stream->stream->total_out;
out = ((*env)->GetPrimitiveArrayCritical (env, buf, 0));
if (out == NULL) {
- throwNewOutOfMemoryError(env, "");
return -1;
}
stream->stream->next_out = (Bytef *) out + off;
diff --git a/archive/src/main/native/java_util_zip_Inflater.c b/archive/src/main/native/java_util_zip_Inflater.c
index 4b30d4e..c04a223 100644
--- a/archive/src/main/native/java_util_zip_Inflater.c
+++ b/archive/src/main/native/java_util_zip_Inflater.c
@@ -104,29 +104,20 @@
{
PORT_ACCESS_FROM_ENV (env);
- jbyte *in;
- U_8 *baseAddr;
JCLZipStream *stream = (JCLZipStream *) ((IDATA) handle);
-
- if (stream->inaddr != NULL) /*Input has already been provided, free the old buffer */
+ if (stream->inaddr != NULL) {
+ /* Input has already been provided, free the old buffer. */
jclmem_free_memory (env, stream->inaddr);
- baseAddr = jclmem_allocate_memory (env, len);
- if (baseAddr == NULL)
- {
- throwNewOutOfMemoryError (env, "");
- return;
- }
+ }
+ U_8* baseAddr = jclmem_allocate_memory (env, len);
+ if (baseAddr == NULL) {
+ throwNewOutOfMemoryError (env, "");
+ return;
+ }
stream->inaddr = baseAddr;
stream->stream->next_in = (Bytef *) baseAddr;
stream->stream->avail_in = len;
- in = ((*env)->GetPrimitiveArrayCritical (env, buf, 0));
- if (in == NULL) {
- throwNewOutOfMemoryError(env, "");
- return;
- }
- memcpy (baseAddr, (in + off), len);
- ((*env)->ReleasePrimitiveArrayCritical (env, buf, in, JNI_ABORT));
- return;
+ (*env)->GetByteArrayRegion(env, buf, off, len, (jbyte*) baseAddr);
}
JNIEXPORT jint JNICALL
diff --git a/archive/src/main/native/sieb.c b/archive/src/main/native/sieb.c
index 6881cf6..4529307 100644
--- a/archive/src/main/native/sieb.c
+++ b/archive/src/main/native/sieb.c
@@ -1,38 +1,52 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#include "sieb.h"
#include "JNIHelp.h"
#include "jni.h"
-#include <malloc.h>
+#include <stdlib.h>
// Throw java.lang.OutOfMemoryError
-void throwNewOutOfMemoryError (JNIEnv * env, const char *message)
-{
+void throwNewOutOfMemoryError(JNIEnv *env, const char *message) {
jniThrowException(env, "java/lang/OutOfMemoryError", message);
}
-void * sieb_malloc (JNIEnv * env, size_t byteCnt) {
- void * adr = malloc(byteCnt);
+void *sieb_malloc(JNIEnv *env, size_t byteCnt) {
+ void *adr = malloc(byteCnt);
if (adr == 0) {
- if (byteCnt == 0)
- throwNewOutOfMemoryError(env, "sieb_malloc(0) NOT ALLOWED");
- else
- throwNewOutOfMemoryError(env, "sieb_malloc");
+ if (byteCnt == 0) {
+ throwNewOutOfMemoryError(env, "sieb_malloc(0) NOT ALLOWED");
+ } else {
+ throwNewOutOfMemoryError(env, "sieb_malloc");
+ }
}
return adr;
}
-void sieb_free (JNIEnv * env, void * adr) {
+void sieb_free(JNIEnv *env, void *adr) {
free(adr);
}
-
-
-void sieb_convertToPlatform (char *path) {
+void sieb_convertToPlatform(char *path) {
char *pathIndex;
pathIndex = path;
while (*pathIndex != '\0') {
- if(*pathIndex == '\\') {
+ if (*pathIndex == '\\') {
*pathIndex = '/';
}
pathIndex++;
diff --git a/archive/src/main/native/sieb.h b/archive/src/main/native/sieb.h
index 541ad90..c32da04 100644
--- a/archive/src/main/native/sieb.h
+++ b/archive/src/main/native/sieb.h
@@ -1,21 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#if !defined(sieb_h)
#define sieb_h
-
#include "JNIHelp.h"
#include "jni.h"
-
-
-void throwNewOutOfMemoryError (JNIEnv * env,
- const char *message);
-
-
-void * sieb_malloc (JNIEnv * env, size_t byteCnt);
-void sieb_free (JNIEnv * env, void * adr);
-
-void sieb_convertToPlatform (char *path);
-
-
+void throwNewOutOfMemoryError(JNIEnv *env, const char *message);
+void *sieb_malloc(JNIEnv *env, size_t byteCnt);
+void sieb_free(JNIEnv *env, void *adr);
+void sieb_convertToPlatform(char *path);
#endif /* sieb_h */
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
index 77fbb15..601fe42 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
@@ -21,10 +21,8 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
-
import junit.framework.TestCase;
-
-import tests.support.Support_Exec;
+import static tests.support.Support_Exec.execAndGetOutput;
import tests.support.resource.Support_Resources;
import java.io.ByteArrayOutputStream;
@@ -32,49 +30,47 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
-import java.util.jar.JarFile;
@TestTargetClass(JarOutputStream.class)
@AndroidOnly("dalvik vm specific")
public class DalvikExecTest extends TestCase {
- String execDalvik1 (String classpath, String mainClass, String arg1)
+ String execDalvik1(String classpath, String mainClass, String arg1)
throws IOException, InterruptedException {
- ArrayList<String> cmdLine = new ArrayList<String>(10);
+ ProcessBuilder builder = new ProcessBuilder();
String base = System.getenv("OUT");
- cmdLine.add(base + "/system/bin/dalvikvm");
+ builder.command().add(base + "/system/bin/dalvikvm");
- cmdLine.add("-Djava.io.tmpdir=/tmp/mc");
- cmdLine.add("-Duser.language=en");
- cmdLine.add("-Duser.region=US");
+ builder.command().add("-Djava.io.tmpdir=/tmp/mc");
+ builder.command().add("-Duser.language=en");
+ builder.command().add("-Duser.region=US");
if ("true".equals(System.getenv("TARGET_SIMULATOR"))) {
// Test against SIMULATOR:
// cmdLine.add("-Xmx512M");
// cmdLine.add("-Xcheck:jni");
- cmdLine.add("-Xbootclasspath:" + System.getProperty("java.boot.class.path"));
+ builder.command().add("-Xbootclasspath:" + System.getProperty("java.boot.class.path"));
} else {
// Test against EMULATOR:
}
- cmdLine.add("-classpath");
- cmdLine.add(classpath);
- cmdLine.add(mainClass);
+ builder.command().add("-classpath");
+ builder.command().add(classpath);
+ builder.command().add(mainClass);
- if (arg1 != null) cmdLine.add(arg1);
+ if (arg1 != null) {
+ builder.command().add(arg1);
+ }
- Object[] res = Support_Exec.execAndDigestOutput(
- cmdLine.toArray(new String[cmdLine.size()]),
- null );
- return Support_Exec.getProcessOutput(res, true);
+ return execAndGetOutput(builder);
}
String execDalvik (String classpath, String mainClass)
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
index 4c209d1..01f5a8c 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
@@ -21,7 +21,8 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
-import tests.support.Support_Exec;
+import static tests.support.Support_Exec.execAndGetOutput;
+import static tests.support.Support_Exec.javaProcessBuilder;
import tests.support.resource.Support_Resources;
import java.io.File;
@@ -73,15 +74,12 @@
jout.close();
-
- // set up the VM parameters
- String[] args = new String[] {"-jar", outputJar.getAbsolutePath()};
-
// execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(outputJar.getAbsolutePath());
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
}
/**
@@ -123,13 +121,12 @@
joutBar.write(getResource(resources, "hyts_Bar.ser"));
joutBar.close();
- String[] args = new String[] {"-jar", fooJar.getAbsolutePath()};
-
// execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(fooJar.getAbsolutePath());
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
// rewrite manifest so it contains not only reference to bar but useless
// entries as well
@@ -139,10 +136,8 @@
joutFoo.write(getResource(resources, "hyts_Foo.ser"));
joutFoo.close();
// execute the JAR and read the result
- res = Support_Exec.execJava(args, null, false);
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
-
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith( "FOOBAR"));
// play with relative file names - put relative path as ../<parent dir
// name>/xx.jar
@@ -154,9 +149,8 @@
joutFoo.write(getResource(resources, "hyts_Foo.ser"));
joutFoo.close();
// execute the JAR and read the result
- res = Support_Exec.execJava(args, null, false);
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith( "FOOBAR"));
}
/**
@@ -199,13 +193,12 @@
joutBar.write(getResource(resources, "hyts_Bar.ser"));
joutBar.close();
- String[] args = new String[] {"-jar", barJar.getAbsolutePath()};
-
// execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(barJar.getAbsolutePath());
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
}
@TestTargetNew(
@@ -229,15 +222,13 @@
joutFoo.write(getResource(resources, "hyts_Bar.ser"));
joutFoo.close();
- String[] args = new String[] {"foo.bar.execjartest.Foo"};
-
// execute the JAR and read the result
- String res = Support_Exec.execJava(args, null,
- new String[] {"CLASSPATH=" + fooJar.getAbsolutePath()}, false);
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.environment().put("CLASSPATH", fooJar.getAbsolutePath());
+ builder.command().add("foo.bar.execjartest.Foo");
- assertTrue(
- "Error executing class from ClassPath : result returned was incorrect.",
- res.startsWith("FOOBAR"));
+ assertTrue("Error executing class from ClassPath",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
// ok - next try - add -cp to path - it should override env
File booJar = File.createTempFile("hyts_", ".jar");
@@ -257,13 +248,14 @@
joutBoo.write(farBody.getBytes("iso-8859-1"));
joutBoo.close();
- res = Support_Exec.execJava(args, new String[] {booJar
- .getAbsolutePath()}, new String[] {"CLASSPATH="
- + fooJar.getAbsolutePath()}, false);
+ builder = javaProcessBuilder();
+ builder.environment().put("CLASSPATH", fooJar.getAbsolutePath());
+ builder.command().add("-cp");
+ builder.command().add(booJar.getAbsolutePath());
+ builder.command().add("foo.bar.execjartest.Foo");
- assertTrue(
- "Error executing class specified by -cp : result returned was incorrect.",
- res.startsWith("BOOFAR"));
+ assertTrue("Error executing class specified by -cp",
+ execAndGetOutput(builder).startsWith("BOOFAR"));
// now add -jar option - it should override env and classpath
Manifest man = new Manifest();
@@ -288,15 +280,15 @@
joutZoo.write(zarBody.getBytes("iso-8859-1"));
joutZoo.close();
- args = new String[] {"-jar", zooJar.getAbsolutePath()};
+ builder = javaProcessBuilder();
+ builder.environment().put("CLASSPATH", fooJar.getAbsolutePath());
+ builder.command().add("-cp");
+ builder.command().add(booJar.getAbsolutePath());
+ builder.command().add("-jar");
+ builder.command().add(zooJar.getAbsolutePath());
- res = Support_Exec.execJava(args, new String[] {booJar
- .getAbsolutePath()}, new String[] {"CLASSPATH="
- + fooJar.getAbsolutePath()}, false);
-
- assertTrue(
- "Error executing class specified by -cp : result returned was incorrect.",
- res.startsWith("ZOOZAR"));
+ assertTrue("Error executing class specified by -jar",
+ execAndGetOutput(builder).startsWith("ZOOZAR"));
}
private static byte[] getResource(File tempDir, String resourceName)
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
index acdad71..b2ecdec 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
@@ -34,7 +34,6 @@
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
-import tests.support.Support_Exec;
import tests.support.resource.Support_Resources;
@TestTargetClass(JarOutputStream.class)
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
index c6f07de..013974c 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
@@ -21,7 +21,8 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
-import tests.support.Support_Exec;
+import static tests.support.Support_Exec.javaProcessBuilder;
+import static tests.support.Support_Exec.execAndGetOutput;
import tests.support.resource.Support_Resources;
import java.io.File;
@@ -72,15 +73,12 @@
man.write(zout);
zout.close();
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(outputZip.getAbsolutePath());
- // set up the VM parameters
- String[] args = new String[] {"-jar", outputZip.getAbsolutePath()};
-
- // execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing ZIP : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ assertTrue("Error executing ZIP",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
}
/**
@@ -124,13 +122,12 @@
zoutBar.write(getResource(resources, "hyts_Bar.ser"));
zoutBar.close();
- String[] args = new String[] {"-jar", fooZip.getAbsolutePath()};
-
// execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(fooZip.getAbsolutePath());
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith( "FOOBAR"));
// rewrite manifest so it contains not only reference to bar but useless
// entries as well
@@ -142,9 +139,8 @@
zoutFoo.write(getResource(resources, "hyts_Foo.ser"));
zoutFoo.close();
// execute the JAR and read the result
- res = Support_Exec.execJava(args, null, false);
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
// play with relative file names - put relative path as ../<parent dir
@@ -159,9 +155,8 @@
zoutFoo.write(getResource(resources, "hyts_Foo.ser"));
zoutFoo.close();
// execute the ZIP and read the result
- res = Support_Exec.execJava(args, null, false);
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
}
@@ -199,13 +194,11 @@
zoutBar.write(getResource(resources, "hyts_Bar.ser"));
zoutBar.close();
- String[] args = new String[] {"-jar", fooJar.getAbsolutePath()};
-
- // execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(fooJar.getAbsolutePath());
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
}
@TestTargetNew(
@@ -244,13 +237,12 @@
joutBar.write(getResource(resources, "hyts_Bar.ser"));
joutBar.close();
- String[] args = new String[] {"-jar", fooZip.getAbsolutePath()};
-
// execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing ZIP : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(fooZip.getAbsolutePath());
+ assertTrue("Error executing ZIP",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
}
/**
@@ -296,13 +288,12 @@
zoutBar.write(getResource(resources, "hyts_Bar.ser"));
zoutBar.close();
- String[] args = new String[] {"-jar", barZip.getAbsolutePath()};
-
// execute the JAR and read the result
- String res = Support_Exec.execJava(args, null, false);
-
- assertTrue("Error executing JAR : result returned was incorrect.", res
- .startsWith("FOOBAR"));
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-jar");
+ builder.command().add(barZip.getAbsolutePath());
+ assertTrue("Error executing JAR",
+ execAndGetOutput(builder).startsWith("FOOBAR"));
}
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
index b025e11..fb326a6 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
@@ -23,6 +23,7 @@
import dalvik.annotation.TestTargetNew;
import tests.support.Support_PlatformFile;
import tests.support.resource.Support_Resources;
+import tests.util.TestEnvironment;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -142,7 +143,6 @@
args = {java.lang.String.class}
)
public void test_ConstructorLjava_lang_String() throws IOException {
- String oldUserDir = System.getProperty("user.dir");
System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
zfile.close(); // about to reopen the same temp file
@@ -167,7 +167,6 @@
// expected
} finally {
System.setSecurityManager(oldSm);
- System.setProperty("user.dir", oldUserDir);
}
}
@@ -271,14 +270,23 @@
Enumeration<? extends ZipEntry> enumeration = zfile.entries();
zfile.close();
- zfile = null;
- boolean pass = false;
+ try {
+ enumeration.nextElement();
+ fail("did not detect closed file");
+ } catch (IllegalStateException expected) {
+ }
+
try {
enumeration.hasMoreElements();
- } catch (IllegalStateException e) {
- pass = true;
+ fail("did not detect closed file");
+ } catch (IllegalStateException expected) {
}
- assertTrue("did not detect closed jar file", pass);
+
+ try {
+ zfile.entries();
+ fail("did not detect closed file");
+ } catch (IllegalStateException expected) {
+ }
}
/**
@@ -349,20 +357,15 @@
method = "getEntry",
args = {java.lang.String.class}
)
- @KnownFailure("Android does not throw IllegalStateException when using "
- + "getEntry() after close().")
public void test_getEntryLjava_lang_String_Ex() throws IOException {
java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
assertNotNull("Could not obtain ZipEntry", zentry);
- int r;
- InputStream in;
zfile.close();
try {
- zentry = zfile.getEntry("File2.txt");
- fail("IllegalStateException expected"); // Android fails here!
+ zfile.getEntry("File2.txt");
+ fail("IllegalStateException expected");
} catch (IllegalStateException ee) {
- // expected
}
}
@@ -435,16 +438,13 @@
method = "size",
args = {}
)
- @KnownFailure("IllegalStateException not thrown when using ZipFile.size() "
- + "after close().")
public void test_size() throws IOException {
assertEquals(6, zfile.size());
zfile.close();
try {
zfile.size();
- fail("IllegalStateException expected"); // Android fails here!
- } catch (IllegalStateException ee) {
- // expected
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException expected) {
}
}
@@ -582,6 +582,7 @@
*/
@Override
protected void tearDown() {
+ TestEnvironment.reset();
try {
if (zfile != null) {
// Note zfile is a user-defined zip file used by other tests and
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
index ee21b13..312c76d 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
@@ -30,7 +30,10 @@
private long rawIndex(int i) {
if (i < 0 || i >= array.length)
throw new IndexOutOfBoundsException("index " + i);
- return base + i * scale;
+ // BEGIN android-changed
+ // avoid memory corruption
+ return base + (long) i * scale;
+ // END android-changed
}
/**
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
index d96f4c2..187acbc 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
@@ -29,7 +29,10 @@
private long rawIndex(int i) {
if (i < 0 || i >= array.length)
throw new IndexOutOfBoundsException("index " + i);
- return base + i * scale;
+ // BEGIN android-changed
+ // avoid memory corruption
+ return base + (long) i * scale;
+ // END android-changed
}
/**
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
index 9a484e6..fff6a1e 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
@@ -30,7 +30,10 @@
private long rawIndex(int i) {
if (i < 0 || i >= array.length)
throw new IndexOutOfBoundsException("index " + i);
- return base + i * scale;
+ // BEGIN android-changed
+ // avoid memory corruption
+ return base + (long) i * scale;
+ // END android-changed
}
/**
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
index 1245eb3..c7c1a5d 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
@@ -25,6 +25,7 @@
import org.apache.harmony.crypto.tests.support.MyCipher;
import tests.support.resource.Support_Resources;
+import tests.util.TestEnvironment;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -86,7 +87,12 @@
fail("No key " + e);
}
}
-
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
/**
* @tests javax.crypto.Cipher#getInstance(java.lang.String)
*/
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java
index d3d0857..63ed789 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java
@@ -57,6 +57,7 @@
import org.apache.harmony.crypto.tests.support.EncryptedPrivateKeyInfoData;
import junit.framework.TestCase;
+import tests.util.TestEnvironment;
@TestTargetClass(EncryptedPrivateKeyInfo.class)
/**
@@ -195,7 +196,12 @@
// {"RSA",null}, // 1.2.840.113549.1.1.1
// {"1.2.840.113549.1.1.1", null},
};
-
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
index d196edc..a5d8d90 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
@@ -22,10 +22,17 @@
import junit.framework.TestCase;
import targets.Cipher;
+import tests.util.TestEnvironment;
@TestTargetClass(Cipher.AESWrap.class)
public class CipherAesWrapTest extends TestCase {
-// 3 cases checked
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
+ // 3 cases checked
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
diff --git a/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java b/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java
new file mode 100644
index 0000000..a62ca3b
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * An optimized handler for efficient publishing of basic log messages.
+ * Implementers should also be subclasses of {@link java.util.logging.Handler}.
+ *
+ * <p>Unlike the default log handler, this API doesn't require intermediate
+ * objects to be allocated for log handling. It also includes a short tag, which
+ * may otherwise need to be calculated for each published message.
+ *
+ * @hide
+ */
+public interface DalvikLogHandler {
+
+ /**
+ * Publishes a log message. Unlike {@link
+ * java.util.logging.Handler#publish(java.util.logging.LogRecord)}, this
+ * method includes only the raw log message. Log messages that were created
+ * with additional fields (parameters, source methods, etc.) will flow
+ * through the conventional channels instead.
+ *
+ * @param tag the short (23 characters or fewer) logger tag identifying
+ * {@code logger}.
+ */
+ void publish(Logger source, String tag, Level level, String message);
+
+ // TODO: support messages with throwables?
+}
\ No newline at end of file
diff --git a/dalvik/src/main/java/dalvik/system/DalvikLogging.java b/dalvik/src/main/java/dalvik/system/DalvikLogging.java
new file mode 100644
index 0000000..b5c7ad5
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/DalvikLogging.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+/**
+ * Utility methods for logging to {@code DalvikHandlers}.
+ *
+ * @hide
+ */
+public final class DalvikLogging {
+ private DalvikLogging() {}
+
+ /**
+ * Returns the short logger tag (up to 23 chars) for the given logger name.
+ * Traditionally loggers are named by fully-qualified Java classes; this
+ * method attempts to return a concise identifying part of such names.
+ */
+ public static String loggerNameToTag(String loggerName) {
+ // Anonymous logger.
+ if (loggerName == null) {
+ return "null";
+ }
+
+ int length = loggerName.length();
+ if (length <= 23) {
+ return loggerName;
+ }
+
+ int lastPeriod = loggerName.lastIndexOf(".");
+ return length - (lastPeriod + 1) <= 23
+ ? loggerName.substring(lastPeriod + 1)
+ : loggerName.substring(loggerName.length() - 23);
+ }
+}
diff --git a/dalvik/src/main/java/dalvik/system/DexClassLoader.java b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
index 73e6fe4..4a440b5 100644
--- a/dalvik/src/main/java/dalvik/system/DexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
@@ -114,7 +114,7 @@
/* open all Zip and DEX files up front */
for (int i = 0; i < length; i++) {
- System.out.println("My path is: " + dexPathList[i]);
+ //System.out.println("My path is: " + dexPathList[i]);
File pathFile = new File(dexPathList[i]);
mFiles[i] = pathFile;
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 365388a..f9411ca 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -284,10 +284,18 @@
public static native boolean cacheRegisterMap(String classAndMethodDesc);
/**
- * Crashes the VM. Seriously. Dumps the stack trace for the current
- * thread and then aborts the VM so you can see the native stack trace.
- * Useful for figuring out how you got somewhere when lots of native
- * code is involved.
+ * Dumps the contents of the VM reference tables (e.g. JNI locals and
+ * globals) to the log file.
+ *
+ * @hide
+ */
+ public static native void dumpReferenceTables();
+
+ /**
+ * Crashes the VM. Seriously. Dumps the interpreter stack trace for
+ * the current thread and then aborts the VM so you can see the native
+ * stack trace. Useful for figuring out how you got somewhere when
+ * lots of native code is involved.
*
* @hide
*/
diff --git a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetDecoderICU.java b/icu/src/main/java/com/ibm/icu4jni/charset/CharsetDecoderICU.java
index 919d865..9c74d68 100644
--- a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetDecoderICU.java
+++ b/icu/src/main/java/com/ibm/icu4jni/charset/CharsetDecoderICU.java
@@ -286,9 +286,11 @@
private final int getArray(CharBuffer out){
if(out.hasArray()){
+ // BEGIN android-changed: take arrayOffset into account
output = out.array();
- outEnd = out.limit();
- return out.position();
+ outEnd = out.arrayOffset() + out.limit();
+ return out.arrayOffset() + out.position();
+ // END android-changed
}else{
outEnd = out.remaining();
// BEGIN android-added
@@ -306,9 +308,11 @@
}
private final int getArray(ByteBuffer in){
if(in.hasArray()){
+ // BEGIN android-changed: take arrayOffset into account
input = in.array();
- inEnd = in.limit();
- return in.position()+savedInputHeldLen;/*exclude the number fo bytes held in previous conversion*/
+ inEnd = in.arrayOffset() + in.limit();
+ return in.arrayOffset() + in.position() + savedInputHeldLen;/*exclude the number fo bytes held in previous conversion*/
+ // END android-changed
}else{
inEnd = in.remaining();
// BEGIN android-added
@@ -331,7 +335,9 @@
}
private final void setPosition(CharBuffer out){
if(out.hasArray()){
- out.position(out.position() + data[OUTPUT_OFFSET]);
+ // BEGIN android-changed: take arrayOffset into account
+ out.position(out.position() + data[OUTPUT_OFFSET] - out.arrayOffset());
+ // END android-changed
}else{
out.put(output,0,data[OUTPUT_OFFSET]);
}
diff --git a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetEncoderICU.java b/icu/src/main/java/com/ibm/icu4jni/charset/CharsetEncoderICU.java
index ec169f4..eada080 100644
--- a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetEncoderICU.java
+++ b/icu/src/main/java/com/ibm/icu4jni/charset/CharsetEncoderICU.java
@@ -328,9 +328,11 @@
//------------------------------------------
private final int getArray(ByteBuffer out) {
if(out.hasArray()){
+ // BEGIN android-changed: take arrayOffset into account
output = out.array();
- outEnd = out.limit();
- return out.position();
+ outEnd = out.arrayOffset() + out.limit();
+ return out.arrayOffset() + out.position();
+ // END android-changed
}else{
outEnd = out.remaining();
// BEGIN android-added
@@ -348,9 +350,11 @@
private final int getArray(CharBuffer in) {
if(in.hasArray()){
+ // BEGIN android-changed: take arrayOffset into account
input = in.array();
- inEnd = in.limit();
- return in.position()+savedInputHeldLen;/*exclude the number fo bytes held in previous conversion*/
+ inEnd = in.arrayOffset() + in.limit();
+ return in.arrayOffset() + in.position() + savedInputHeldLen;/*exclude the number fo bytes held in previous conversion*/
+ // END android-changed
}else{
inEnd = in.remaining();
// BEGIN android-added
@@ -378,7 +382,9 @@
// array backing the buffer directly and wrote to
// it, so just just set the position and return.
// This is done to avoid the creation of temp array.
- out.position(out.position() + data[OUTPUT_OFFSET] );
+ // BEGIN android-changed: take arrayOffset into account
+ out.position(out.position() + data[OUTPUT_OFFSET] - out.arrayOffset());
+ // END android-changed
} else {
out.put(output, 0, data[OUTPUT_OFFSET]);
}
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java b/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
index c8f5372..5ef1161 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
@@ -22,10 +22,10 @@
public abstract class BreakIterator implements Cloneable
{
- protected static int BI_CHAR_INSTANCE = 1;
- protected static int BI_WORD_INSTANCE = 2;
- protected static int BI_LINE_INSTANCE = 3;
- protected static int BI_SENT_INSTANCE = 4;
+ protected static final int BI_CHAR_INSTANCE = 1;
+ protected static final int BI_WORD_INSTANCE = 2;
+ protected static final int BI_LINE_INSTANCE = 3;
+ protected static final int BI_SENT_INSTANCE = 4;
protected int type = 0;
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java b/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
index 7e8a000..9e9401d 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
@@ -122,7 +122,7 @@
{
if (m_hash_ == 0)
{
- if (m_bytes_ != null || m_bytes_.length != 0)
+ if (m_bytes_ != null && m_bytes_.length != 0)
{
int len = m_bytes_.length;
int inc = ((len - 32) / 32) + 1;
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
index 5bee1fd..104336e 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
@@ -48,6 +48,13 @@
private boolean posPrefNull;
private boolean posSuffNull;
+ /**
+ * Cache the BigDecimal form of the multiplier. This is null until we've
+ * formatted a BigDecimal (with a multipler that is not 1), or the user has
+ * explicitly called {@link #setMultiplier(int)} with any multiplier.
+ */
+ private transient BigDecimal multiplierBigDecimal = null;
+
public DecimalFormat(String pattern, DecimalFormatSymbols icuSymbols) {
this.addr = icuSymbols.getAddr();
this.symbols = icuSymbols;
@@ -118,6 +125,14 @@
return result;
}
+ private BigDecimal applyMultiplier(BigDecimal valBigDecimal) {
+ if (multiplierBigDecimal == null) {
+ multiplierBigDecimal = BigDecimal.valueOf(getMultiplier());
+ }
+ // Get new value by multiplying multiplier.
+ return valBigDecimal.multiply(multiplierBigDecimal);
+ }
+
@Override
public StringBuffer format(Object value, StringBuffer buffer, FieldPosition field) {
@@ -139,6 +154,9 @@
return buffer.append(result);
} else if(number instanceof BigDecimal) {
BigDecimal valBigDecimal = (BigDecimal) number;
+ if (getMultiplier() != 1) {
+ valBigDecimal = applyMultiplier(valBigDecimal);
+ }
StringBuilder val = new StringBuilder();
val.append(valBigDecimal.unscaledValue().toString(10));
int scale = valBigDecimal.scale();
@@ -233,6 +251,9 @@
valBigInteger.toString(10), null, null, attributes, 0);
} else if(number instanceof BigDecimal) {
BigDecimal valBigDecimal = (BigDecimal) number;
+ if (getMultiplier() != 1) {
+ valBigDecimal = applyMultiplier(valBigDecimal);
+ }
StringBuilder val = new StringBuilder();
val.append(valBigDecimal.unscaledValue().toString(10));
int scale = valBigDecimal.scale();
@@ -441,6 +462,8 @@
public void setMultiplier(int value) {
NativeDecimalFormat.setAttribute(this.addr,
UNumberFormatAttribute.UNUM_MULTIPLIER.ordinal(), value);
+ // Update the cached BigDecimal for multiplier.
+ multiplierBigDecimal = BigDecimal.valueOf(value);
}
public void setNegativePrefix(String value) {
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormatSymbols.java b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormatSymbols.java
index 98463e4..ebda335 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormatSymbols.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormatSymbols.java
@@ -24,7 +24,7 @@
import java.util.Locale;
import java.util.ResourceBundle;
-public class DecimalFormatSymbols {
+public class DecimalFormatSymbols implements Cloneable {
private int addr;
diff --git a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
index 0460fde..086f8d4 100644
--- a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
+++ b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
@@ -114,7 +114,7 @@
isoLanguages = getISOLanguagesNative();
}
- return isoLanguages;
+ return isoLanguages.clone();
}
/**
@@ -128,7 +128,7 @@
isoCountries = getISOCountriesNative();
}
- return isoCountries;
+ return isoCountries.clone();
}
/**
@@ -142,7 +142,7 @@
availableLocales = getAvailableLocalesNative();
}
- return availableLocales;
+ return availableLocales.clone();
}
/**
@@ -157,7 +157,7 @@
availableTimezones = TimeZone.getAvailableIDs();
}
- return availableTimezones;
+ return availableTimezones.clone();
}
/**
@@ -264,17 +264,25 @@
if (locale == null) {
locale = defaultLocale;
}
-
+
// If locale == default and the default locale hasn't changed since
// DefaultTimeZones loaded, return the cached names.
// TODO: We should force a reboot if the default locale changes.
if (defaultLocale.equals(locale) && DefaultTimeZones.locale.equals(defaultLocale)) {
- return DefaultTimeZones.names;
+ return clone2dStringArray(DefaultTimeZones.names);
}
return createTimeZoneNamesFor(locale);
}
+ private static String[][] clone2dStringArray(String[][] array) {
+ String[][] result = new String[array.length][];
+ for (int i = 0; i < array.length; ++i) {
+ result[i] = array[i].clone();
+ }
+ return result;
+ }
+
// --- Specialized ResourceBundle subclasses ------------------------------
/**
diff --git a/icu/src/main/native/BidiWrapperInterface.c b/icu/src/main/native/BidiWrapperInterface.c
index 2c6b3cd..19ac520 100644
--- a/icu/src/main/native/BidiWrapperInterface.c
+++ b/icu/src/main/native/BidiWrapperInterface.c
@@ -15,18 +15,17 @@
* limitations under the License.
*/
-#include <stdlib.h>
-#include <unicode/ubidi.h>
-#include <string.h>
#include "BidiWrapperInterface.h"
+#include "ErrorCode.h"
+#include "unicode/ubidi.h"
+#include <stdlib.h>
+#include <string.h>
typedef struct {
UBiDi *pBiDi;
void *embeddingLevels;
} BiDiData;
-void check_fail (JNIEnv * env, int err);
-
JNIEXPORT jlong JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1open
(JNIEnv * env, jclass clazz)
{
@@ -43,62 +42,52 @@
ubidi_close ((*data).pBiDi);
- if ((*data).embeddingLevels != NULL)
- free((*data).embeddingLevels);
- free(data);
+ free((*data).embeddingLevels);
+ free(data);
}
JNIEXPORT void JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1setPara
(JNIEnv * env, jclass clazz, jlong pBiDi, jcharArray text, jint length,
- jbyte paraLevel, jbyteArray embeddingLevels)
+ jbyte paraLevel, jbyteArray newEmbeddingLevels)
{
- UErrorCode err = 0;
- jchar *_text = NULL;
BiDiData *data = (BiDiData *)pBiDi;
- /* Remembering old embedding levels */
- void *embLvls = (*data).embeddingLevels;
-
- _text = (*env)->GetCharArrayElements (env, text, NULL);
+ void *oldEmbeddingLevels = (*data).embeddingLevels;
- if (embeddingLevels != NULL)
- {
- jbyte *el = (*env)->GetByteArrayElements (env, embeddingLevels, NULL);
- (*data).embeddingLevels = malloc(length);
- memcpy(((*data).embeddingLevels), el, length);
- (*env)->ReleaseByteArrayElements (env, embeddingLevels, el, 0);
- } else
- {
- (*data).embeddingLevels = NULL;
- }
-
- ubidi_setPara ((*data).pBiDi, _text, length, paraLevel,
- ((*data).embeddingLevels), &err);
- check_fail (env, err);
-
- /* Freeing old embedding levels */
- if (embLvls != NULL) {
- free(embLvls);
+ // Copy the new embedding levels from the Java heap to the native heap.
+ if (newEmbeddingLevels != NULL) {
+ (*data).embeddingLevels = malloc(length);
+ (*env)->GetByteArrayRegion(env, newEmbeddingLevels, 0, length,
+ (*data).embeddingLevels);
+ } else {
+ (*data).embeddingLevels = NULL;
}
+ UErrorCode err = 0;
+ jchar* _text = (*env)->GetCharArrayElements(env, text, NULL);
+ ubidi_setPara ((*data).pBiDi, _text, length, paraLevel,
+ ((*data).embeddingLevels), &err);
(*env)->ReleaseCharArrayElements (env, text, _text, 0);
+ free(oldEmbeddingLevels);
+
+ icu4jni_error(env, err);
}
JNIEXPORT jlong JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1setLine
(JNIEnv * env, jclass clazz, jlong pBiDi, jint start, jint limit)
{
- UErrorCode err = 0;
- BiDiData *data = (BiDiData *)pBiDi;
- BiDiData *lineData = (BiDiData *) malloc(sizeof(BiDiData));
- (*lineData).embeddingLevels = NULL;
+ UErrorCode err = 0;
+ BiDiData *data = (BiDiData *)pBiDi;
+ BiDiData *lineData = (BiDiData *) malloc(sizeof(BiDiData));
+ (*lineData).embeddingLevels = NULL;
- (*lineData).pBiDi = ubidi_openSized (limit - start, 0, &err);
- check_fail (env, err);
+ (*lineData).pBiDi = ubidi_openSized (limit - start, 0, &err);
+ if (icu4jni_error(env, err)) {
+ return 0;
+ }
- ubidi_setLine ((*data).pBiDi, start, limit, (*lineData).pBiDi,
- &err);
- check_fail (env, err);
-
- return (jlong) lineData;
+ ubidi_setLine ((*data).pBiDi, start, limit, (*lineData).pBiDi, &err);
+ icu4jni_error(env, err);
+ return (jlong) lineData;
}
JNIEXPORT jint JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getDirection
@@ -125,76 +114,57 @@
JNIEXPORT jbyteArray JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getLevels
(JNIEnv * env, jclass clazz, jlong pBiDi)
{
- UErrorCode err = 0;
- const UBiDiLevel *levels = NULL;
- jbyteArray result = NULL;
- int len = 0;
- BiDiData *data = (BiDiData *)pBiDi;
+ BiDiData *data = (BiDiData *)pBiDi;
- levels = ubidi_getLevels ((*data).pBiDi, &err);
- check_fail (env, err);
+ UErrorCode err = 0;
+ const UBiDiLevel* levels = ubidi_getLevels((*data).pBiDi, &err);
+ if (icu4jni_error(env, err)) {
+ return NULL;
+ }
- len = ubidi_getLength ((*data).pBiDi);
- result = (*env)->NewByteArray (env, len);
- (*env)->SetByteArrayRegion (env, result, 0, len, (jbyte *) levels);
+ int len = ubidi_getLength((*data).pBiDi);
+ jbyteArray result = (*env)->NewByteArray(env, len);
+ (*env)->SetByteArrayRegion(env, result, 0, len, (jbyte*) levels);
- return result;
+ return result;
}
JNIEXPORT jint JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1countRuns
(JNIEnv * env, jclass clazz, jlong pBiDi)
{
- UErrorCode err = 0;
- BiDiData *data = (BiDiData *)pBiDi;
+ BiDiData *data = (BiDiData *)pBiDi;
- int count = ubidi_countRuns ((*data).pBiDi, &err);
- check_fail (env, err);
-
- return count;
+ UErrorCode err = 0;
+ int count = ubidi_countRuns ((*data).pBiDi, &err);
+ icu4jni_error(env, err);
+ return count;
}
JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getRuns
(JNIEnv * env, jclass clz, jlong pBiDi)
{
- int runCount = 0;
- int start = 0;
- int limit = 0;
- int i = 0;
- UBiDiLevel level = 0;
- jclass run_clazz = 0;
- jmethodID initID = 0;
- jobject run = 0;
- jobjectArray runs;
- UErrorCode err = 0;
- BiDiData *data = (BiDiData *)pBiDi;
+ BiDiData* data = (BiDiData*) pBiDi;
- run_clazz = (*env)->FindClass (env, "org/apache/harmony/text/BidiRun");
- initID = (*env)->GetMethodID (env, run_clazz, "<init>", "(III)V");
-
- runCount = ubidi_countRuns ((*data).pBiDi, &err);
- check_fail (env, err);
-
- runs = (*env)->NewObjectArray(env, runCount,run_clazz, NULL);
- for (i = 0; i < runCount; i++) {
- ubidi_getLogicalRun((*data).pBiDi, start, &limit, &level);
- run = (*env)->NewObject (env, run_clazz, initID, start, limit, level);
- (*env)->SetObjectArrayElement(env, runs, i, run);
- start = limit;
- }
- return runs;
-}
-
-void
-check_fail (JNIEnv * env, int err)
-{
- char message[] = "ICU Internal Error: ";
-
- if (U_FAILURE (err))
- {
- sprintf (message, "ICU Internal Error: %d", err);
- jniThrowException(env, "java/lang/RuntimeException",
- message);
+ UErrorCode err = 0;
+ int runCount = ubidi_countRuns((*data).pBiDi, &err);
+ if (icu4jni_error(env, err)) {
+ return 0;
}
+
+ jclass bidiRunClass = (*env)->FindClass(env, "org/apache/harmony/text/BidiRun");
+ jmethodID bidiRunConstructor = (*env)->GetMethodID(env, bidiRunClass, "<init>", "(III)V");
+ jobjectArray runs = (*env)->NewObjectArray(env, runCount, bidiRunClass, NULL);
+ UBiDiLevel level = 0;
+ int start = 0;
+ int limit = 0;
+ int i = 0; // TODO: switch this file to C++!
+ for (i = 0; i < runCount; ++i) {
+ ubidi_getLogicalRun((*data).pBiDi, start, &limit, &level);
+ jobject run = (*env)->NewObject(env, bidiRunClass, bidiRunConstructor, start, limit, level);
+ (*env)->SetObjectArrayElement(env, runs, i, run);
+ start = limit;
+ }
+ return runs;
}
JNIEXPORT jintArray JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1reorderVisual
diff --git a/icu/src/main/native/CollationInterface.c b/icu/src/main/native/CollationInterface.c
index 86246ac..c669649 100644
--- a/icu/src/main/native/CollationInterface.c
+++ b/icu/src/main/native/CollationInterface.c
@@ -172,13 +172,11 @@
static jint getNormalization(JNIEnv *env, jclass obj,
jint address) {
- UErrorCode status = U_ZERO_ERROR;
- const UCollator *collator = (const UCollator *)(int)address;
- if(U_FAILURE(status)){
- icu4jni_error(env, status);
- }
- return (jint)ucol_getAttribute(collator,UCOL_NORMALIZATION_MODE,&status);
-
+ const UCollator* collator = (const UCollator*) address;
+ UErrorCode status = U_ZERO_ERROR;
+ jint result = ucol_getAttribute(collator, UCOL_NORMALIZATION_MODE, &status);
+ icu4jni_error(env, status);
+ return result;
}
/**
@@ -192,12 +190,10 @@
static void setNormalization(JNIEnv *env, jclass obj, jint address,
jint mode) {
+ const UCollator* collator = (const UCollator*) address;
UErrorCode status = U_ZERO_ERROR;
- const UCollator *collator = (const UCollator *)(int)address;
- if(U_FAILURE(status)){
- icu4jni_error(env, status);
- }
- ucol_setAttribute(collator,UCOL_NORMALIZATION_MODE,mode,&status);
+ ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, mode, &status);
+ icu4jni_error(env, status);
}
@@ -324,12 +320,11 @@
* error has occured or if the end of string has been reached
*/
static jint next(JNIEnv *env, jclass obj, jint address) {
- UCollationElements *iterator = (UCollationElements *)(int)address;
- UErrorCode status = U_ZERO_ERROR;
- jint result = ucol_next(iterator, &status);
-
- icu4jni_error(env, status);
- return result;
+ UCollationElements *iterator = (UCollationElements *) address;
+ UErrorCode status = U_ZERO_ERROR;
+ jint result = ucol_next(iterator, &status);
+ icu4jni_error(env, status);
+ return result;
}
/**
@@ -343,14 +338,10 @@
* @exception thrown if creation of the UCollator fails
*/
static jint openCollator__(JNIEnv *env, jclass obj) {
- jint result;
- UErrorCode status = U_ZERO_ERROR;
-
- result = (jint)ucol_open(NULL, &status);
- if ( icu4jni_error(env, status) != FALSE)
- return 0;
-
- return result;
+ UErrorCode status = U_ZERO_ERROR;
+ jint result = ucol_open(NULL, &status);
+ icu4jni_error(env, status);
+ return result;
}
@@ -368,19 +359,18 @@
static jint openCollator__Ljava_lang_String_2(JNIEnv *env,
jclass obj, jstring locale) {
- /* this will be null terminated */
- const char *localestr = (*env)->GetStringUTFChars(env, locale, 0);
- jint result=0;
- UErrorCode status = U_ZERO_ERROR;
+ /* this will be null terminated */
+ const char* localeStr = (*env)->GetStringUTFChars(env, locale, NULL);
+ if (localeStr == NULL) {
+ icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR);
+ return 0;
+ }
- if(localestr){
- result = (jint)ucol_open(localestr, &status);
- (*env)->ReleaseStringUTFChars(env, locale, localestr);
- icu4jni_error(env, status);
- }else{
- icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR);
- }
- return result;
+ UErrorCode status = U_ZERO_ERROR;
+ jint result = ucol_open(localeStr, &status);
+ (*env)->ReleaseStringUTFChars(env, locale, localeStr);
+ icu4jni_error(env, status);
+ return result;
}
/**
@@ -586,4 +576,3 @@
return jniRegisterNativeMethods(_env, "com/ibm/icu4jni/text/NativeCollation",
gMethods, NELEM(gMethods));
}
-
diff --git a/icu/src/main/native/DecimalFormatInterface.cpp b/icu/src/main/native/DecimalFormatInterface.cpp
index 7e37d6c..f553e0a 100644
--- a/icu/src/main/native/DecimalFormatInterface.cpp
+++ b/icu/src/main/native/DecimalFormatInterface.cpp
@@ -29,33 +29,6 @@
#include <string.h>
#include "cutils/log.h"
-
-static UBool icuError(JNIEnv *env, UErrorCode errorcode)
-{
- const char *emsg = u_errorName(errorcode);
- jclass exception;
-
- if (U_FAILURE(errorcode)) {// errorcode > U_ZERO_ERROR && errorcode < U_ERROR_LIMIT) {
- switch (errorcode) {
- case U_ILLEGAL_ARGUMENT_ERROR :
- exception = env->FindClass("java/lang/IllegalArgumentException");
- break;
- case U_INDEX_OUTOFBOUNDS_ERROR :
- case U_BUFFER_OVERFLOW_ERROR :
- exception = env->FindClass("java/lang/ArrayIndexOutOfBoundsException");
- break;
- case U_UNSUPPORTED_ERROR :
- exception = env->FindClass("java/lang/UnsupportedOperationException");
- break;
- default :
- exception = env->FindClass("java/lang/RuntimeException");
- }
-
- return (env->ThrowNew(exception, emsg) != 0);
- }
- return 0;
-}
-
static jint openDecimalFormatImpl(JNIEnv *env, jclass clazz, jstring locale,
jstring pattern) {
@@ -78,7 +51,7 @@
env->ReleaseStringUTFChars(locale, localeChars);
// check for an error
- if ( icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
return 0;
}
@@ -115,8 +88,8 @@
// release previously allocated space
env->ReleaseStringChars(text, textChars);
- // check if an error occured
- icuError(env, status);
+ // check if an error occurred
+ icu4jni_error(env, status);
}
static jstring getSymbol(JNIEnv *env, jclass clazz, jint addr, jint symbol) {
@@ -144,7 +117,7 @@
reslenneeded=unum_getSymbol(fmt, (UNumberFormatSymbol) symbol, result,
resultlength, &status);
}
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
return NULL;
}
@@ -189,7 +162,7 @@
env->ReleaseStringChars(text, textChars);
- icuError(env, status);
+ icu4jni_error(env, status);
}
static jstring getTextAttribute(JNIEnv *env, jclass clazz, jint addr,
@@ -219,7 +192,7 @@
(UNumberFormatTextAttribute) symbol, result, resultlength,
&status);
}
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
return NULL;
}
@@ -246,7 +219,7 @@
env->ReleaseStringChars(pattern, pattChars);
- icuError(env, status);
+ icu4jni_error(env, status);
}
static jstring toPatternImpl(JNIEnv *env, jclass clazz, jint addr,
@@ -274,7 +247,7 @@
reslenneeded=unum_toPattern(fmt, localized, result, resultlength,
&status);
}
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
return NULL;
}
@@ -335,7 +308,7 @@
res->extract(result, reslenneeded + 1, status);
}
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
free(attrBuffer->buffer);
free(attrBuffer);
free(result);
@@ -444,7 +417,7 @@
res->extract(result, reslenneeded + 1, status);
}
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
free(attrBuffer->buffer);
free(attrBuffer);
free(result);
@@ -510,7 +483,7 @@
// env->ReleaseStringUTFChars(value, valueUTF);
if (scale < 0) {
- icuError(env, U_ILLEGAL_ARGUMENT_ERROR);
+ icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR);
return NULL;
}
@@ -532,6 +505,8 @@
const char *digits = (isPositive ? valueChars : valueChars + 1);
int length = strlen(digits);
+ DecimalFormat* fmt = reinterpret_cast<DecimalFormat*>(static_cast<uintptr_t>(addr));
+
// The length of our digit list buffer must be the actual string length + 3,
// because ICU will append some additional characters at the head and at the
// tail of the string, in order to keep strtod() happy:
@@ -551,7 +526,8 @@
digitList.fDecimalAt = digitList.fCount - scale;
digitList.fIsPositive = isPositive;
- digitList.fRoundingMode = DecimalFormat::kRoundHalfUp;
+ digitList.fRoundingMode = fmt->getRoundingMode();
+ digitList.round(fmt->getMaximumFractionDigits() + digitList.fDecimalAt);
UChar *result = NULL;
@@ -567,8 +543,6 @@
attrBuffer->bufferSize = 128;
attrBuffer->buffer = (char *) calloc(129 * sizeof(char), 1);
- DecimalFormat *fmt = (DecimalFormat *)(int)addr;
-
UnicodeString res;
fmt->subformat(res, fp, attrBuffer, digitList, isInteger);
@@ -582,7 +556,7 @@
res.extract(result, reslenneeded + 1, status);
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
if(fieldType != NULL) {
env->ReleaseStringUTFChars(fieldType, fieldName);
}
@@ -671,28 +645,12 @@
static jobject parse(JNIEnv *env, jclass clazz, jint addr, jstring text,
jobject position) {
-
- const char * textUTF = env->GetStringUTFChars(text, NULL);
- env->ReleaseStringUTFChars(text, textUTF);
-
- const char * parsePositionClassName = "java/text/ParsePosition";
- const char * longClassName = "java/lang/Long";
- const char * doubleClassName = "java/lang/Double";
- const char * bigDecimalClassName = "java/math/BigDecimal";
- const char * bigIntegerClassName = "java/math/BigInteger";
-
- UErrorCode status = U_ZERO_ERROR;
-
- UNumberFormat *fmt = (UNumberFormat *)(int)addr;
-
- jchar *str = (UChar *)env->GetStringChars(text, NULL);
- int strlength = env->GetStringLength(text);
-
- jclass parsePositionClass = env->FindClass(parsePositionClassName);
- jclass longClass = env->FindClass(longClassName);
- jclass doubleClass = env->FindClass(doubleClassName);
- jclass bigDecimalClass = env->FindClass(bigDecimalClassName);
- jclass bigIntegerClass = env->FindClass(bigIntegerClassName);
+ // TODO: cache these?
+ jclass parsePositionClass = env->FindClass("java/text/ParsePosition");
+ jclass longClass = env->FindClass("java/lang/Long");
+ jclass doubleClass = env->FindClass("java/lang/Double");
+ jclass bigDecimalClass = env->FindClass("java/math/BigDecimal");
+ jclass bigIntegerClass = env->FindClass("java/math/BigInteger");
jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass,
"getIndex", "()I");
@@ -707,27 +665,26 @@
jmethodID bigIntegerInitMethodID = env->GetMethodID(bigIntegerClass, "<init>", "(Ljava/lang/String;)V");
jmethodID doubleValueMethodID = env->GetMethodID(bigDecimalClass, "doubleValue", "()D");
- bool resultAssigned;
- int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);
-
// make sure the ParsePosition is valid. Actually icu4c would parse a number
// correctly even if the parsePosition is set to -1, but since the RI fails
// for that case we have to fail too
+ int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);
+ const int strlength = env->GetStringLength(text);
if(parsePos < 0 || parsePos > strlength) {
return NULL;
}
-
- Formattable res;
-
- const UnicodeString src((UChar*)str, strlength, strlength);
+
ParsePosition pp;
-
pp.setIndex(parsePos);
DigitList digits;
-
+
+ UNumberFormat *fmt = (UNumberFormat *)(int)addr;
+ Formattable res;
+ bool resultAssigned;
+ jchar *str = (UChar *)env->GetStringChars(text, NULL);
+ const UnicodeString src((UChar*)str, strlength, strlength);
((const DecimalFormat*)fmt)->parse(src, resultAssigned, res, pp, FALSE, digits);
-
env->ReleaseStringChars(text, str);
if(pp.getErrorIndex() == -1) {
@@ -738,20 +695,14 @@
return NULL;
}
- Formattable::Type numType;
- numType = res.getType();
+ Formattable::Type numType = res.getType();
UErrorCode fmtStatus;
double resultDouble;
long resultLong;
int64_t resultInt64;
- UnicodeString resultString;
jstring resultStr;
- int resLength;
- const char * resultUTF;
jobject resultObject1, resultObject2;
- jdouble doubleTest;
- jchar * result;
if (resultAssigned)
{
@@ -809,7 +760,7 @@
UNumberFormat *result = unum_clone(fmt, &status);
- if(icuError(env, status) != FALSE) {
+ if(icu4jni_error(env, status) != FALSE) {
return 0;
}
diff --git a/icu/src/main/native/ErrorCode.c b/icu/src/main/native/ErrorCode.c
index b3e43cd..94c4239 100644
--- a/icu/src/main/native/ErrorCode.c
+++ b/icu/src/main/native/ErrorCode.c
@@ -8,50 +8,32 @@
*/
#include "ErrorCode.h"
-
-/* private data members ----------------------------------------------------*/
+#include "JNIHelp.h"
/**
-* Name of the java runtime exception classes
-*/
-#define ILLEGALARGUMENTEXCEPTION_ "java/lang/IllegalArgumentException"
-#define ARRAYINDEXOUTOFBOUNDSEXCEPTION_ "java/lang/ArrayIndexOutOfBoundsException"
-#define UNSUPPORTEDOPERATIONEXCEPTION_ "java/lang/UnsupportedOperationException"
-#define RUNTIMEEXCEPTION_ "java/lang/RuntimeException"
-
-/* public methods ---------------------------------------------------------*/
-
-/**
-* Checks if an error has occured.
-* Throws a generic Java RuntimeException if an error has occured.
-* @param env JNI environment variable
-* @param errorcode code to determine if it is an erro
-* @return 0 if errorcode is not an error, 1 if errorcode is an error, but the
+* Checks if an error has occurred, throwing a suitable exception if so.
+* @param env JNI environment
+* @param errorCode code to determine if it is an error
+* @return 0 if errorCode is not an error, 1 if errorCode is an error, but the
* creation of the exception to be thrown fails
-* @exception thrown if errorcode represents an error
+ * @exception thrown if errorCode represents an error
*/
-UBool icu4jni_error(JNIEnv *env, UErrorCode errorcode)
+UBool icu4jni_error(JNIEnv *env, UErrorCode errorCode)
{
- const char *emsg = u_errorName(errorcode);
- jclass exception;
-
- if (errorcode > U_ZERO_ERROR && errorcode < U_ERROR_LIMIT) {
- switch (errorcode) {
- case U_ILLEGAL_ARGUMENT_ERROR :
- exception = (*env)->FindClass(env, ILLEGALARGUMENTEXCEPTION_);
- break;
- case U_INDEX_OUTOFBOUNDS_ERROR :
- case U_BUFFER_OVERFLOW_ERROR :
- exception = (*env)->FindClass(env, ARRAYINDEXOUTOFBOUNDSEXCEPTION_);
- break;
- case U_UNSUPPORTED_ERROR :
- exception = (*env)->FindClass(env, UNSUPPORTEDOPERATIONEXCEPTION_);
- break;
- default :
- exception = (*env)->FindClass(env, RUNTIMEEXCEPTION_);
+ const char* message = u_errorName(errorCode);
+ if (errorCode <= U_ZERO_ERROR || errorCode >= U_ERROR_LIMIT) {
+ return 0;
}
-
- return ((*env)->ThrowNew(env, exception, emsg) != 0);
- }
- return 0;
+
+ switch (errorCode) {
+ case U_ILLEGAL_ARGUMENT_ERROR:
+ return jniThrowException(env, "java/lang/IllegalArgumentException", message);
+ case U_INDEX_OUTOFBOUNDS_ERROR:
+ case U_BUFFER_OVERFLOW_ERROR:
+ return jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", message);
+ case U_UNSUPPORTED_ERROR:
+ return jniThrowException(env, "java/lang/UnsupportedOperationException", message);
+ default:
+ return jniThrowException(env, "java/lang/RuntimeException", message);
+ }
}
diff --git a/icu/src/main/native/ErrorCode.h b/icu/src/main/native/ErrorCode.h
index a5bbfc6..e42a519 100644
--- a/icu/src/main/native/ErrorCode.h
+++ b/icu/src/main/native/ErrorCode.h
@@ -13,6 +13,10 @@
#include "unicode/utypes.h"
#include "unicode/putil.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* Checks if an error has occured.
* Throws a generic Java RuntimeException if an error has occured.
@@ -24,4 +28,8 @@
*/
UBool icu4jni_error(JNIEnv *env, UErrorCode errorcode);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/icu/src/main/native/RBNFInterface.cpp b/icu/src/main/native/RBNFInterface.cpp
index d9bf460..c7486e1 100644
--- a/icu/src/main/native/RBNFInterface.cpp
+++ b/icu/src/main/native/RBNFInterface.cpp
@@ -25,32 +25,6 @@
#include <stdlib.h>
#include <string.h>
-static UBool icuError(JNIEnv *env, UErrorCode errorcode)
-{
- const char *emsg = u_errorName(errorcode);
- jclass exception;
-
- if (errorcode > U_ZERO_ERROR && errorcode < U_ERROR_LIMIT) {
- switch (errorcode) {
- case U_ILLEGAL_ARGUMENT_ERROR :
- exception = env->FindClass("java/lang/IllegalArgumentException");
- break;
- case U_INDEX_OUTOFBOUNDS_ERROR :
- case U_BUFFER_OVERFLOW_ERROR :
- exception = env->FindClass("java/lang/ArrayIndexOutOfBoundsException");
- break;
- case U_UNSUPPORTED_ERROR :
- exception = env->FindClass("java/lang/UnsupportedOperationException");
- break;
- default :
- exception = env->FindClass("java/lang/RuntimeException");
- }
-
- return (env->ThrowNew(exception, emsg) != 0);
- }
- return 0;
-}
-
static jint openRBNFImpl1(JNIEnv* env, jclass clazz,
jint type, jstring locale) {
@@ -72,7 +46,7 @@
} else if(type == 3) {
style = URBNF_COUNT;
} else {
- icuError(env, U_ILLEGAL_ARGUMENT_ERROR);
+ icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR);
}
Locale loc = Locale::createFromName(localeChars);
@@ -84,7 +58,7 @@
env->ReleaseStringUTFChars(locale, localeChars);
// check for an error
- if ( icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
return 0;
}
@@ -117,7 +91,7 @@
env->ReleaseStringUTFChars(locale, localeChars);
// check for an error
- if ( icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
return 0;
}
@@ -183,7 +157,7 @@
res.extract(result, reslenneeded + 1, status);
}
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
free(result);
return NULL;
}
@@ -245,7 +219,7 @@
res.extract(result, reslenneeded + 1, status);
}
- if (icuError(env, status) != FALSE) {
+ if (icu4jni_error(env, status) != FALSE) {
free(result);
return NULL;
}
@@ -265,22 +239,11 @@
jobject position, jboolean lenient) {
// LOGI("ENTER parseRBNFImpl");
-
- const char * parsePositionClassName = "java/text/ParsePosition";
- const char * longClassName = "java/lang/Long";
- const char * doubleClassName = "java/lang/Double";
-
-
- UErrorCode status = U_ZERO_ERROR;
-
- UNumberFormat *fmt = (UNumberFormat *)(int)addr;
-
- jchar *str = (UChar *)env->GetStringChars(text, NULL);
- int strlength = env->GetStringLength(text);
-
- jclass parsePositionClass = env->FindClass(parsePositionClassName);
- jclass longClass = env->FindClass(longClassName);
- jclass doubleClass = env->FindClass(doubleClassName);
+
+ // TODO: cache these?
+ jclass parsePositionClass = env->FindClass("java/text/ParsePosition");
+ jclass longClass = env->FindClass("java/lang/Long");
+ jclass doubleClass = env->FindClass("java/lang/Double");
jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass,
"getIndex", "()I");
@@ -292,22 +255,25 @@
jmethodID longInitMethodID = env->GetMethodID(longClass, "<init>", "(J)V");
jmethodID dblInitMethodID = env->GetMethodID(doubleClass, "<init>", "(D)V");
- int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);
-
// make sure the ParsePosition is valid. Actually icu4c would parse a number
// correctly even if the parsePosition is set to -1, but since the RI fails
// for that case we have to fail too
+ int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);
+ const int strlength = env->GetStringLength(text);
if(parsePos < 0 || parsePos > strlength) {
return NULL;
}
-
+
Formattable res;
-
+
+ jchar *str = (UChar *)env->GetStringChars(text, NULL);
+
const UnicodeString src((UChar*)str, strlength, strlength);
ParsePosition pp;
pp.setIndex(parsePos);
+ UNumberFormat *fmt = (UNumberFormat *)(int)addr;
if(lenient) {
unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_TRUE);
}
@@ -328,35 +294,23 @@
return NULL;
}
- Formattable::Type numType;
- numType = res.getType();
- UErrorCode fmtStatus;
-
- double resultDouble;
- long resultLong;
- int64_t resultInt64;
-
- switch(numType) {
- case Formattable::kDouble:
- resultDouble = res.getDouble();
- env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
- return env->NewObject(doubleClass, dblInitMethodID,
- (jdouble) resultDouble);
- case Formattable::kLong:
- resultLong = res.getLong();
- env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
- return env->NewObject(longClass, longInitMethodID,
- (jlong) resultLong);
- case Formattable::kInt64:
- resultInt64 = res.getInt64();
- env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
- return env->NewObject(longClass, longInitMethodID,
- (jlong) resultInt64);
- default:
- break;
+ Formattable::Type numType = res.getType();
+ if (numType == Formattable::kDouble) {
+ double resultDouble = res.getDouble();
+ env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
+ return env->NewObject(doubleClass, dblInitMethodID,
+ (jdouble) resultDouble);
+ } else if (numType == Formattable::kLong) {
+ long resultLong = res.getLong();
+ env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
+ return env->NewObject(longClass, longInitMethodID, (jlong) resultLong);
+ } else if (numType == Formattable::kInt64) {
+ int64_t resultInt64 = res.getInt64();
+ env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
+ return env->NewObject(longClass, longInitMethodID, (jlong) resultInt64);
+ } else {
+ return NULL;
}
-
- return NULL;
}
static JNINativeMethod gMethods[] = {
diff --git a/icu/src/main/native/RegExInterface.cpp b/icu/src/main/native/RegExInterface.cpp
index afa5cc4..0ca3d06 100644
--- a/icu/src/main/native/RegExInterface.cpp
+++ b/icu/src/main/native/RegExInterface.cpp
@@ -32,12 +32,12 @@
* character data it refers to (but does not have a copy of), so we can
* manage memory properly.
*/
-typedef struct RegExDataStruct {
+struct RegExData {
// A pointer to the ICU regular expression
URegularExpression* regex;
// A pointer to (a copy of) the input text that *we* manage
jchar* text;
-} RegExData;
+};
static void throwPatternSyntaxException(JNIEnv* env, UErrorCode status,
jstring pattern, UParseError error)
@@ -63,8 +63,8 @@
uregex_close(data->regex);
}
- if (data->text != NULL && data->text != &EMPTY_STRING) {
- free(data->text);
+ if (data->text != &EMPTY_STRING) {
+ delete[] data->text;
}
free(data);
@@ -125,8 +125,8 @@
return;
}
- if (data->text != NULL && data->text != &EMPTY_STRING) {
- free(data->text);
+ if (data->text != &EMPTY_STRING) {
+ delete[] data->text;
data->text = NULL;
}
@@ -134,11 +134,9 @@
if (textLen == 0) {
data->text = &EMPTY_STRING;
} else {
- jchar const * textRaw = env->GetStringChars(text, NULL);
- data->text = (jchar*)malloc((textLen + 1) * sizeof(jchar));
- memcpy(data->text, textRaw, textLen * sizeof(jchar));
+ data->text = new jchar[textLen + 1];
+ env->GetStringRegion(text, 0, textLen, data->text);
data->text[textLen] = 0;
- env->ReleaseStringChars(text, textRaw);
}
uregex_setText(data->regex, data->text, textLen, &status);
diff --git a/icu/src/main/native/ResourceInterface.cpp b/icu/src/main/native/ResourceInterface.cpp
index a88e15c..731cf3f 100644
--- a/icu/src/main/native/ResourceInterface.cpp
+++ b/icu/src/main/native/ResourceInterface.cpp
@@ -40,32 +40,6 @@
jclass string_class;
-static UBool icuError(JNIEnv *env, UErrorCode errorcode)
-{
- const char *emsg = u_errorName(errorcode);
- jclass exception;
-
- if (U_FAILURE(errorcode)) {
- switch (errorcode) {
- case U_ILLEGAL_ARGUMENT_ERROR :
- exception = env->FindClass("java/lang/IllegalArgumentException");
- break;
- case U_INDEX_OUTOFBOUNDS_ERROR :
- case U_BUFFER_OVERFLOW_ERROR :
- exception = env->FindClass("java/lang/ArrayIndexOutOfBoundsException");
- break;
- case U_UNSUPPORTED_ERROR :
- exception = env->FindClass("java/lang/UnsupportedOperationException");
- break;
- default :
- exception = env->FindClass("java/lang/RuntimeException");
- }
-
- return (env->ThrowNew(exception, emsg) != 0);
- }
- return 0;
-}
-
static Locale getLocale(JNIEnv *env, jstring locale) {
const char *name = env->GetStringUTFChars(locale, NULL);
Locale result = Locale::createFromName(name);
diff --git a/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java b/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
new file mode 100644
index 0000000..1b95075
--- /dev/null
+++ b/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ibm.icu4jni.util;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static final Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(com.ibm.icu4jni.util.ResourcesTest.class);
+ return suite;
+ }
+}
diff --git a/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java b/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java
new file mode 100644
index 0000000..4112d0b
--- /dev/null
+++ b/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ibm.icu4jni.util;
+
+public class ResourcesTest extends junit.framework.TestCase {
+ public void test_getISOLanguages() throws Exception {
+ // Check that corrupting our array doesn't affect other callers.
+ assertNotNull(Resources.getISOLanguages()[0]);
+ Resources.getISOLanguages()[0] = null;
+ assertNotNull(Resources.getISOLanguages()[0]);
+ }
+
+ public void test_getISOCountries() throws Exception {
+ // Check that corrupting our array doesn't affect other callers.
+ assertNotNull(Resources.getISOCountries()[0]);
+ Resources.getISOCountries()[0] = null;
+ assertNotNull(Resources.getISOCountries()[0]);
+ }
+
+ public void test_getAvailableLocales() throws Exception {
+ // Check that corrupting our array doesn't affect other callers.
+ assertNotNull(Resources.getAvailableLocales()[0]);
+ Resources.getAvailableLocales()[0] = null;
+ assertNotNull(Resources.getAvailableLocales()[0]);
+ }
+
+ public void test_getKnownTimezones() throws Exception {
+ // Check that corrupting our array doesn't affect other callers.
+ assertNotNull(Resources.getKnownTimezones()[0]);
+ Resources.getKnownTimezones()[0] = null;
+ assertNotNull(Resources.getKnownTimezones()[0]);
+ }
+
+ public void test_getDisplayTimeZones() throws Exception {
+ // Check that corrupting our array doesn't affect other callers.
+ assertNotNull(Resources.getDisplayTimeZones(null)[0]);
+ Resources.getDisplayTimeZones(null)[0] = null;
+ assertNotNull(Resources.getDisplayTimeZones(null)[0]);
+ // getDisplayTimezones actually returns a String[][] rather than a String[].
+ assertNotNull(Resources.getDisplayTimeZones(null)[0][0]);
+ Resources.getDisplayTimeZones(null)[0][0] = null;
+ assertNotNull(Resources.getDisplayTimeZones(null)[0][0]);
+ }
+}
diff --git a/logging/src/main/java/java/util/logging/FileHandler.java b/logging/src/main/java/java/util/logging/FileHandler.java
index e1eba9e..dd7790e 100644
--- a/logging/src/main/java/java/util/logging/FileHandler.java
+++ b/logging/src/main/java/java/util/logging/FileHandler.java
@@ -571,7 +571,7 @@
* the log record to publish.
*/
@Override
- public void publish(LogRecord record) {
+ public synchronized void publish(LogRecord record) {
super.publish(record);
flush();
if (limit > 0 && output.getLength() >= limit) {
diff --git a/logging/src/main/java/java/util/logging/LogManager.java b/logging/src/main/java/java/util/logging/LogManager.java
index 308daaf..413efb3 100644
--- a/logging/src/main/java/java/util/logging/LogManager.java
+++ b/logging/src/main/java/java/util/logging/LogManager.java
@@ -17,6 +17,14 @@
package java.util.logging;
+// BEGIN android-note
+// this file contains cleaned up documentation and style for contribution
+// upstream.
+// javax.management support (MBeans) has been dropped.
+// END android-note
+
+import org.apache.harmony.logging.internal.nls.Messages;
+
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.BufferedInputStream;
@@ -24,28 +32,14 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-// BEGIN android-removed
-//import java.lang.management.ManagementFactory;
-//import java.lang.reflect.Method;
-// END android-removed
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.Iterator;
import java.util.Properties;
-import java.util.Set;
import java.util.StringTokenizer;
-// BEGIN android-removed
-//import javax.management.MBeanServer;
-//import javax.management.ObjectInstance;
-//import javax.management.ObjectName;
-// END android-removed
-
-import org.apache.harmony.logging.internal.nls.Messages;
-
/**
* {@code LogManager} is used to maintain configuration properties of the
* logging framework, and to manage a hierarchical namespace of all named
@@ -126,20 +120,19 @@
* the property file. The root logger's level can be defined by the property
* named as ".level".
* <p>
- * All methods on this type can be taken as being thread safe.
- *
+ * This class is thread safe. It is an error to synchronize on a
+ * {@code LogManager} while synchronized on a {@code Logger}.
*/
public class LogManager {
- // The line separator of the underlying OS
- // Use privileged code to read the line.separator system property
+ /** The line separator of the underlying OS. */
private static final String lineSeparator = getPrivilegedSystemProperty("line.separator"); //$NON-NLS-1$
- // The shared logging permission
+ /** The shared logging permission. */
private static final LoggingPermission perm = new LoggingPermission(
"control", null); //$NON-NLS-1$
- // the singleton instance
+ /** The singleton instance. */
static LogManager manager;
/**
@@ -192,10 +185,10 @@
// FIXME: use weak reference to avoid heap memory leak
private Hashtable<String, Logger> loggers;
- // the configuration properties
+ /** The configuration properties */
private Properties props;
- // the property change listener
+ /** the property change listener */
private PropertyChangeSupport listeners;
static {
@@ -234,7 +227,7 @@
/**
* Default constructor. This is not public because there should be only one
* {@code LogManager} instance, which can be get by
- * {@code LogManager.getLogManager(}. This is protected so that
+ * {@code LogManager.getLogManager()}. This is protected so that
* application can subclass the object.
*/
protected LogManager() {
@@ -318,17 +311,17 @@
parentName = parentName.substring(0, lastSeparator);
parent = loggers.get(parentName);
if (parent != null) {
- logger.internalSetParent(parent);
+ setParent(logger, parent);
break;
} else if (getProperty(parentName + ".level") != null || //$NON-NLS-1$
getProperty(parentName + ".handlers") != null) { //$NON-NLS-1$
parent = Logger.getLogger(parentName);
- logger.internalSetParent(parent);
+ setParent(logger, parent);
break;
}
}
if (parent == null && null != (parent = loggers.get(""))) { //$NON-NLS-1$
- logger.internalSetParent(parent);
+ setParent(logger, parent);
}
// find children
@@ -348,7 +341,7 @@
});
if (null != oldParent) {
// -- remove from old parent as the parent has been changed
- oldParent.removeChild(child);
+ oldParent.children.remove(child);
}
}
}
@@ -408,7 +401,6 @@
* not have the required permissions to perform this action.
*/
public void readConfiguration() throws IOException {
- checkAccess();
// check config class
String configClassName = System
.getProperty("java.util.logging.config.class"); //$NON-NLS-1$
@@ -443,7 +435,7 @@
"logging.properties"), 8192);
}
// END android-added
- readConfigurationImpl(input);
+ readConfiguration(input);
} finally {
if (input != null) {
try {
@@ -491,6 +483,13 @@
reset();
props.load(ins);
+ // The RI treats the root logger as special. For compatibility, always
+ // update the root logger's handlers.
+ Logger root = loggers.get("");
+ if (root != null) {
+ root.setManager(this);
+ }
+
// parse property "config" and apply setting
String configs = props.getProperty("config"); //$NON-NLS-1$
if (null != configs) {
@@ -544,7 +543,7 @@
* if security manager exists and it determines that caller does
* not have the required permissions to perform this action.
*/
- public void reset() {
+ public synchronized void reset() {
checkAccess();
props = new Properties();
Enumeration<String> names = getLoggerNames();
@@ -593,4 +592,67 @@
checkAccess();
listeners.removePropertyChangeListener(l);
}
+
+ /**
+ * Returns a named logger associated with the supplied resource bundle.
+ *
+ * @param resourceBundleName the resource bundle to associate, or null for
+ * no associated resource bundle.
+ */
+ synchronized Logger getOrCreate(String name, String resourceBundleName) {
+ Logger result = getLogger(name);
+ if (result == null) {
+ result = new Logger(name, resourceBundleName);
+ addLogger(result);
+ }
+ return result;
+ }
+
+
+ /**
+ * Sets the parent of this logger in the namespace. Callers must first
+ * {@link #checkAccess() check security}.
+ *
+ * @param newParent
+ * the parent logger to set.
+ */
+ synchronized void setParent(Logger logger, Logger newParent) {
+ logger.parent = newParent;
+
+ if (logger.levelObjVal == null) {
+ setLevelRecursively(logger, null);
+ }
+ newParent.children.add(logger);
+ logger.updateDalvikLogHandler(); // android-only
+ }
+
+ /**
+ * Sets the level on {@code logger} to {@code newLevel}. Any child loggers
+ * currently inheriting their level from {@code logger} will be updated
+ * recursively.
+ *
+ * @param newLevel the new minimum logging threshold. If null, the logger's
+ * parent level will be used; or {@code Level.INFO} for loggers with no
+ * parent.
+ */
+ synchronized void setLevelRecursively(Logger logger, Level newLevel) {
+ int previous = logger.levelIntVal;
+ logger.levelObjVal = newLevel;
+
+ if (newLevel == null) {
+ logger.levelIntVal = logger.parent != null
+ ? logger.parent.levelIntVal
+ : Level.INFO.intValue();
+ } else {
+ logger.levelIntVal = newLevel.intValue();
+ }
+
+ if (previous != logger.levelIntVal) {
+ for (Logger child : logger.children) {
+ if (child.levelObjVal == null) {
+ setLevelRecursively(child, null);
+ }
+ }
+ }
+ }
}
diff --git a/logging/src/main/java/java/util/logging/Logger.java b/logging/src/main/java/java/util/logging/Logger.java
index fe124d3..e4f317d 100644
--- a/logging/src/main/java/java/util/logging/Logger.java
+++ b/logging/src/main/java/java/util/logging/Logger.java
@@ -17,15 +17,26 @@
package java.util.logging;
+// BEGIN android-note
+// this file contains cleaned up documentation and style for contribution
+// upstream
+// It also contains Android-specific optimizations that aren't appropriate for
+// general purpose platforms
+// END android-note
+
+import dalvik.system.DalvikLogHandler;
+import dalvik.system.DalvikLogging;
+import org.apache.harmony.logging.internal.nls.Messages;
+
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
-
-import org.apache.harmony.logging.internal.nls.Messages;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* Loggers are used to log records to certain outputs, including file, console,
@@ -67,51 +78,158 @@
*/
public class Logger {
- /**
- * The global logger is provided as convenience for casual use.
- */
+ // BEGIN android-only
+ /** A handler for use when no handler optimization is possible. */
+ private static final DalvikLogHandler GENERAL_LOG_HANDLER = new DalvikLogHandler() {
+ public void publish(Logger source, String tag, Level level, String message) {
+ LogRecord record = new LogRecord(level, message);
+ record.setLoggerName(source.name);
+ source.setResourceBundle(record);
+ source.log(record);
+ }
+ };
+ // END android-only
+
+ /** The global logger is provided as convenience for casual use. */
public final static Logger global = new Logger("global", null); //$NON-NLS-1$
- // the name of this logger
+ /**
+ * When converting the concurrent collection of handlers to an array, we
+ * always pass a zero-length array to avoid size miscalculations. Passing
+ * properly-sized arrays is non-atomic, and risks a null element in the
+ * result.
+ */
+ private static final Handler[] EMPTY_HANDLERS_ARRAY = new Handler[0];
+
+ /** The name of this logger. */
private volatile String name;
- // the parent logger of this logger
- private Logger parent;
+ /** The parent logger of this logger. */
+ Logger parent;
- // the logging level of this logger
- private volatile Level levelObjVal;
+ /** The logging level of this logger, or null if none is set. */
+ volatile Level levelObjVal;
- // the logging level as int of this logger
- private volatile int levelIntVal;
+ /**
+ * The effective logging level of this logger. In order of preference this
+ * is the first applicable of:
+ * <ol>
+ * <li>the int value of this logger's {@link #levelObjVal}
+ * <li>the logging level of the parent
+ * <li>the default level ({@link Level#INFO})
+ * </ol>
+ */
+ volatile int levelIntVal = Level.INFO.intValue();
- // the filter
+ /** The filter. */
private Filter filter;
- // the name of the resource bundle used to localize logging messages
- private String resBundleName;
-
- // the loaded resource bundle according to the specified name
- private ResourceBundle resBundle;
-
- // the handlers attached to this logger
- private List<Handler> handlers;
-
- /*
- * flag indicating whether to notify parent's handlers on receiving a log
- * request
+ /**
+ * The resource bundle used to localize logging messages. If null, no
+ * localization will be performed.
*/
- private boolean notifyParentHandlers;
+ private volatile String resourceBundleName;
- // flag indicating whether this logger is named or anonymous
- private boolean isNamed;
+ /** The loaded resource bundle according to the specified name. */
+ private volatile ResourceBundle resourceBundle;
- private List<Logger> childs;
+ /**
+ * The handlers attached to this logger. Eagerly initialized and
+ * concurrently modified.
+ */
+ private final List<Handler> handlers = new CopyOnWriteArrayList<Handler>();
- private LogManager manager;
+ /** True to notify the parent's handlers of each log message. */
+ private boolean notifyParentHandlers = true;
- // BEGIN android-changed
- private volatile boolean handlerInited;
- // END android-changed
+ /**
+ * Indicates whether this logger is named. Only {@link #getAnonymousLogger
+ * anonymous loggers} are unnamed.
+ */
+ private boolean isNamed = true;
+
+ /**
+ * Child loggers. Should be accessed only while synchronized on {@code
+ * LogManager.getLogManager()}.
+ */
+ final List<Logger> children = new ArrayList<Logger>();
+
+ // BEGIN android-only
+ /** the tag used for optimized logging. Derived from the logger name. */
+ private final String androidTag;
+
+ /** Handler delegate for either optimized or standard logging. */
+ private volatile DalvikLogHandler dalvikLogHandler = GENERAL_LOG_HANDLER;
+
+ /**
+ * We've optimized for the common case: logging to a single handler that
+ * implements {@link DalvikLogHandler}. This is how Android framework
+ * applications are configured by default.
+ *
+ * <p>This optimization has been measured to show a 2.75x improvement in
+ * throughput in the common case: 154ns vs. 56ns per message on a Cortex-A8.
+ * Direct use of {@code android.util.Log} takes 29ns per message.
+ *
+ * <p>Each time the handler configuration changes, either directly or
+ * indirectly, it's necessary to either turn on or off this optimization.
+ * When the optimization is off, {@link #dalvikLogHandler} is assigned to
+ * {@link #GENERAL_LOG_HANDLER} which can satisfy arbitrary configuration.
+ * When the optimization is possible, {@link #dalvikLogHandler} is assigned
+ * to the user's efficient implementation. In pratice this is usually the
+ * {@code com.android.internal.logging.AndroidHandler}.
+ */
+ void updateDalvikLogHandler() {
+ DalvikLogHandler newLogHandler = GENERAL_LOG_HANDLER;
+
+ Logger parent = this.parent;
+
+ if (getClass() != Logger.class) {
+ /*
+ * Do nothing. Subclasses aren't eligible for the optimization
+ * because they may override methods like getHandlers() or
+ * log(LogRecord).
+ */
+
+ } else if (parent == null) {
+ // we use an iterator rather than size()+get() for safe concurrency
+ Iterator<Handler> h = handlers.iterator();
+ if (h.hasNext()) {
+ Handler firstHandler = h.next();
+ if (!h.hasNext() && firstHandler instanceof DalvikLogHandler) {
+ /*
+ * At this point, we're eligible for the optimization. We've
+ * satisfied these constraints:
+ * 1. This is not a subclass of logger
+ * 2. This is a root logger (no parent)
+ * 3. There is exactly one handler installed
+ * 4. That handler is a DalvikLogHandler
+ */
+ newLogHandler = (DalvikLogHandler) firstHandler;
+ }
+ }
+ } else if (handlers.isEmpty() && notifyParentHandlers) {
+ /*
+ * At this point, we're eligible for the optimization if our parent
+ * logger is eligible. We've satisfied these constraints:
+ * 1. This is not a subclass of logger
+ * 2. our parent exists
+ * 3. we have no handlers of our own
+ * 4. we notify our parent's handlers
+ */
+ newLogHandler = parent.dalvikLogHandler;
+ }
+
+ if (newLogHandler == this.dalvikLogHandler) {
+ return;
+ }
+
+ this.dalvikLogHandler = newLogHandler;
+
+ for (Logger logger : children) {
+ logger.updateDalvikLogHandler();
+ }
+ }
+ // END android-only
/**
* Constructs a {@code Logger} object with the supplied name and resource
@@ -129,55 +247,12 @@
* if the specified resource bundle can not be loaded.
*/
protected Logger(String name, String resourceBundleName) {
- // try to load the specified resource bundle first
- if (null == resourceBundleName) {
- this.resBundleName = null;
- this.resBundle = null;
- } else {
- this.resBundle = loadResourceBundle(resourceBundleName);
- this.resBundleName = resourceBundleName;
- }
this.name = name;
- this.parent = null;
- this.filter = null;
- this.childs = new ArrayList<Logger>();
- this.notifyParentHandlers = true;
- // any logger is not anonymous by default
- this.isNamed = true;
-
- // -- 'null' means that level will be inherited from parent (see
- // getLevel)
- // -- Level.INFO is default level if we don't set it. It will be
- // -- changed to parent level or to configLevel after adding to the
- // -- family tree. As of this, actually, setting to Level.INFO is
- // -- not needed here.
- this.levelObjVal = null;
- this.levelIntVal = Level.INFO.intValue();
- }
-
- // -- should be called under the lm lock
- private void setLevelImpl(Level newLevel) {
- // update levels for the whole hierarchy
- int oldVal = levelIntVal;
- levelObjVal = newLevel;
- if (null == newLevel) {
- levelIntVal = null != parent ? parent.levelIntVal : Level.INFO
- .intValue();
- } else {
- levelIntVal = newLevel.intValue();
- }
- if (oldVal != levelIntVal) {
- forceChildsToInherit();
- }
- }
-
- // -- should be called under the lm lock
- private void forceChildsToInherit() {
- for (Logger child : childs) {
- if (null == child.levelObjVal) { // should inherit
- child.setLevelImpl(null);
- }
- }
+ initResourceBundle(resourceBundleName);
+ // BEGIN android-only
+ this.androidTag = DalvikLogging.loggerNameToTag(name);
+ updateDalvikLogHandler();
+ // END android-only
}
/**
@@ -197,7 +272,7 @@
return Thread.currentThread().getContextClassLoader();
}
});
- if (null != cl) {
+ if (cl != null) {
try {
return ResourceBundle.getBundle(resourceBundleName, Locale
.getDefault(), cl);
@@ -211,7 +286,7 @@
return ClassLoader.getSystemClassLoader();
}
});
- if (null != cl) {
+ if (cl != null) {
try {
return ResourceBundle.getBundle(resourceBundleName, Locale
.getDefault(), cl);
@@ -237,7 +312,7 @@
return classes[index].getClassLoader();
}
});
- if (null == cl) {
+ if (cl == null) {
continue;
}
return ResourceBundle.getBundle(resourceBundleName, Locale
@@ -280,66 +355,38 @@
* if the specified resource bundle can not be loaded.
*/
public static Logger getAnonymousLogger(String resourceBundleName) {
- final Logger l = new Logger(null, resourceBundleName);
- l.isNamed = false;
- l.internalSetParent(LogManager.getLogManager().getLogger("")); //$NON-NLS-1$
- return l;
+ Logger result = new Logger(null, resourceBundleName);
+ result.isNamed = false;
+ LogManager logManager = LogManager.getLogManager();
+ logManager.setParent(result, logManager.getLogger(""));
+ return result;
}
- /*
- * Check whether the same resource bundle has been specified.
- * Synchronize to ensure the consistency between resource bundle
- * and its name.
+ /**
+ * Initializes this logger's resource bundle.
+ *
+ * @throws IllegalArgumentException if this logger's resource bundle already
+ * exists and is different from the resource bundle specified.
*/
- private static void updateResourceBundle(Logger l, String resourceBundleName) {
- synchronized (l) {
- if (null == l.getResourceBundleName()) {
- if (null == resourceBundleName) {
- return;
- }
- /*
- * load the resource bundle if none is specified before
- */
- l.resBundle = loadResourceBundle(resourceBundleName);
- l.resBundleName = resourceBundleName;
- } else if (!l.getResourceBundleName().equals(resourceBundleName)) {
- /*
- * throw exception if the specified resource bundles are
- * inconsistent with each other, i.e., different names
- */
+ private synchronized void initResourceBundle(String resourceBundleName) {
+ String current = this.resourceBundleName;
+
+ if (current != null) {
+ if (current.equals(resourceBundleName)) {
+ return;
+ } else {
// logging.9=The specified resource bundle name "{0}" is
// inconsistent with the existing one "{1}".
throw new IllegalArgumentException(Messages.getString(
"logging.9", //$NON-NLS-1$
- resourceBundleName, l.getResourceBundleName()));
+ resourceBundleName, current));
}
}
- }
- /*
- * Gets a named logger associated with the supplied resource bundle. This
- * method accepts null resource bundle name. The method body is synchronized
- * on the instance of the LogManager to insure the consistency of the whole
- * operation.
- */
- private static Logger getLoggerWithRes(String name,
- String resourceBundleName, boolean hasResourceName) {
- LogManager man = LogManager.getLogManager();
- Logger l = null;
- synchronized (man) {
- // Try to find an existing logger with the specified name
- l = man.getLogger(name);
- // If no existing logger with the same name, create a new one
- if (null == l) {
- l = new Logger(name, resourceBundleName);
- man.addLogger(l);
- return l;
- }
+ if (resourceBundleName != null) {
+ this.resourceBundle = loadResourceBundle(resourceBundleName);
+ this.resourceBundleName = resourceBundleName;
}
- if (hasResourceName) {
- updateResourceBundle(l, resourceBundleName);
- }
- return l;
}
/**
@@ -354,7 +401,7 @@
* If the specified resource bundle can not be loaded.
*/
public static Logger getLogger(String name) {
- return getLoggerWithRes(name, null, false);
+ return LogManager.getLogManager().getOrCreate(name, null);
}
/**
@@ -374,7 +421,10 @@
* @return a named logger.
*/
public static Logger getLogger(String name, String resourceBundleName) {
- return getLoggerWithRes(name, resourceBundleName, true);
+ Logger result = LogManager.getLogManager()
+ .getOrCreate(name, resourceBundleName);
+ result.initResourceBundle(resourceBundleName);
+ return result;
}
/**
@@ -388,7 +438,7 @@
* have the required permission.
*/
public void addHandler(Handler handler) {
- if (null == handler) {
+ if (handler == null) {
// logging.A=The 'handler' parameter is null.
throw new NullPointerException(Messages.getString("logging.A")); //$NON-NLS-1$
}
@@ -396,64 +446,55 @@
if (this.isNamed) {
LogManager.getLogManager().checkAccess();
}
- initHandler();
- synchronized (this) {
- this.handlers.add(handler);
- }
+ this.handlers.add(handler);
+ updateDalvikLogHandler(); // android-only
}
- /*
- * Be cautious to avoid deadlock when using this method, it gets lock on manager
- * at first, and then gets lock on this Logger, so any methods should not hold
- * lock on this Logger when invoking this method.
+ /**
+ * Set the logger's manager and initializes its configuration from the
+ * manager's properties.
*/
- private void initHandler() {
- if (!handlerInited) {
- synchronized (this) {
- if (!handlerInited) {
- // BEGIN android-added
- /*
- * Force LogManager to be initialized, since its
- * class init code performs necessary one-time setup.
- */
- LogManager.getLogManager();
- // END android-added
- if (handlers == null) {
- handlers = new ArrayList<Handler>();
- }
- if (manager == null) {
- return;
- }
-
- String handlerStr = manager
- .getProperty("".equals(name) ? "handlers" : name + ".handlers"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- if (null == handlerStr) {
- return;
- }
- String[] strs = handlerStr.split(",|\\s"); //$NON-NLS-1$
- for (int i = 0; i < strs.length; i++) {
- String handlerName = strs[i];
- if (handlerName.equals("")) { //$NON-NLS-1$
- continue;
- }
- // BEGIN android-changed
- // deal with non-existing handler
- try {
- Handler handler = (Handler) LogManager.getInstanceByClass(handlerName);
- handlers.add(handler);
- String level = manager.getProperty(handlerName + ".level"); //$NON-NLS-1$
- if (null != level) {
- handler.setLevel(Level.parse(level));
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- // END android-changed
- }
- handlerInited = true;
- }
+ @SuppressWarnings("nls")
+ void setManager(LogManager manager) {
+ String levelProperty = manager.getProperty(name + ".level");
+ if (levelProperty != null) {
+ try {
+ manager.setLevelRecursively(Logger.this, Level.parse(levelProperty));
+ } catch (IllegalArgumentException invalidLevel) {
+ invalidLevel.printStackTrace();
}
}
+
+ String handlersPropertyName = "".equals(name) ? "handlers" : name + ".handlers";
+ String handlersProperty = manager.getProperty(handlersPropertyName);
+ if (handlersProperty != null) {
+ for (String handlerName : handlersProperty.split(",|\\s")) {
+ if (handlerName.equals("")) {
+ continue;
+ }
+
+ final Handler handler;
+ try {
+ handler = (Handler) LogManager.getInstanceByClass(handlerName);
+ } catch (Exception invalidHandlerName) {
+ invalidHandlerName.printStackTrace();
+ continue;
+ }
+
+ try {
+ String level = manager.getProperty(handlerName + ".level");
+ if (level != null) {
+ handler.setLevel(Level.parse(level));
+ }
+ } catch (Exception invalidLevel) {
+ invalidLevel.printStackTrace();
+ }
+
+ handlers.add(handler);
+ }
+ }
+
+ updateDalvikLogHandler(); // android-only
}
/**
@@ -462,10 +503,7 @@
* @return an array of all the handlers associated with this logger.
*/
public Handler[] getHandlers() {
- initHandler();
- synchronized (this) {
- return handlers.toArray(new Handler[handlers.size()]);
- }
+ return handlers.toArray(EMPTY_HANDLERS_ARRAY);
}
/**
@@ -483,13 +521,11 @@
if (this.isNamed) {
LogManager.getLogManager().checkAccess();
}
- if (null == handler) {
+ if (handler == null) {
return;
}
- initHandler();
- synchronized (this) {
- this.handlers.remove(handler);
- }
+ this.handlers.remove(handler);
+ updateDalvikLogHandler(); // android-only
}
/**
@@ -540,12 +576,11 @@
*/
public void setLevel(Level newLevel) {
// Anonymous loggers can always set the level
+ LogManager logManager = LogManager.getLogManager();
if (this.isNamed) {
- LogManager.getLogManager().checkAccess();
+ logManager.checkAccess();
}
- synchronized (LogManager.getLogManager()) {
- setLevelImpl(newLevel);
- }
+ logManager.setLevelRecursively(this, newLevel);
}
/**
@@ -576,6 +611,7 @@
LogManager.getLogManager().checkAccess();
}
this.notifyParentHandlers = notifyParentHandlers;
+ updateDalvikLogHandler(); // android-only
}
/**
@@ -589,28 +625,6 @@
}
/**
- * Sets the parent of this logger in the namespace. This method should
- * usually be used by the {@code LogManager} object only. This method does
- * not check security.
- *
- * @param newParent
- * the parent logger to set.
- */
- void internalSetParent(Logger newParent) {
- // All hierarchy related modifications should get LogManager lock at
- // first
- synchronized (LogManager.getLogManager()) {
- parent = newParent;
- // -- update level after setting a parent.
- // -- if level == null we should inherit the parent's level
- if (null == levelObjVal) {
- setLevelImpl(levelObjVal);
- }
- newParent.addChild(this);
- }
- }
-
- /**
* Sets the parent of this logger in the namespace. This method should be
* used by the {@code LogManager} object only.
*
@@ -621,21 +635,15 @@
* have the required permission.
*/
public void setParent(Logger parent) {
- if (null == parent) {
+ if (parent == null) {
// logging.B=The 'parent' parameter is null.
throw new NullPointerException(Messages.getString("logging.B")); //$NON-NLS-1$
}
+
// even anonymous loggers are checked
- LogManager.getLogManager().checkAccess();
- internalSetParent(parent);
- }
-
- final void addChild(Logger logger) {
- childs.add(logger);
- }
-
- final void removeChild(Logger child) {
- childs.remove(child);
+ LogManager logManager = LogManager.getLogManager();
+ logManager.checkAccess();
+ logManager.setParent(this, parent);
}
/**
@@ -655,7 +663,7 @@
* @return the loaded resource bundle used by this logger.
*/
public ResourceBundle getResourceBundle() {
- return this.resBundle;
+ return this.resourceBundle;
}
/**
@@ -666,7 +674,7 @@
* @return the name of the loaded resource bundle used by this logger.
*/
public String getResourceBundleName() {
- return this.resBundleName;
+ return this.resourceBundleName;
}
/**
@@ -698,28 +706,19 @@
return internalIsLoggable(l);
}
- /*
+ /**
* Sets the resource bundle and its name for a supplied LogRecord object.
* This method first tries to use this logger's resource bundle if any,
* otherwise try to inherit from this logger's parent, recursively up the
- * namespace. Synchronize to ensure the consistency between resource bundle
- * and its name.
+ * namespace.
*/
private void setResourceBundle(LogRecord record) {
- if (null != this.resBundleName) {
- record.setResourceBundle(this.resBundle);
- record.setResourceBundleName(this.resBundleName);
- } else {
- Logger anyParent = this.parent;
- // no need to synchronize here, because if resBundleName
- // is not null, there is no chance to modify it
- while (null != anyParent) {
- if (null != anyParent.resBundleName) {
- record.setResourceBundle(anyParent.resBundle);
- record.setResourceBundleName(anyParent.resBundleName);
- return;
- }
- anyParent = anyParent.parent;
+ for (Logger p = this; p != null; p = p.parent) {
+ String resourceBundleName = p.resourceBundleName;
+ if (resourceBundleName != null) {
+ record.setResourceBundle(p.resourceBundle);
+ record.setResourceBundleName(resourceBundleName);
+ return;
}
}
}
@@ -735,14 +734,16 @@
* the method name.
*/
public void entering(String sourceClass, String sourceMethod) {
- if (internalIsLoggable(Level.FINER)) {
- LogRecord record = new LogRecord(Level.FINER, "ENTRY"); //$NON-NLS-1$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(Level.FINER)) {
+ return;
}
+
+ LogRecord record = new LogRecord(Level.FINER, "ENTRY"); //$NON-NLS-1$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -759,15 +760,17 @@
* the parameter for the method call.
*/
public void entering(String sourceClass, String sourceMethod, Object param) {
- if (internalIsLoggable(Level.FINER)) {
- LogRecord record = new LogRecord(Level.FINER, "ENTRY" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { param });
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(Level.FINER)) {
+ return;
}
+
+ LogRecord record = new LogRecord(Level.FINER, "ENTRY" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { param });
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -783,25 +786,28 @@
* @param params
* an array of parameters for the method call.
*/
+ @SuppressWarnings("nls")
public void entering(String sourceClass, String sourceMethod,
Object[] params) {
- if (internalIsLoggable(Level.FINER)) {
- String msg = "ENTRY"; //$NON-NLS-1$
- if (null != params) {
- StringBuilder msgBuffer = new StringBuilder("ENTRY"); //$NON-NLS-1$
- for (int i = 0; i < params.length; i++) {
- msgBuffer.append(" {" + i + "}"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- msg = msgBuffer.toString();
- }
- LogRecord record = new LogRecord(Level.FINER, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(params);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(Level.FINER)) {
+ return;
}
+
+ String msg = "ENTRY";
+ if (params != null) {
+ StringBuilder msgBuffer = new StringBuilder("ENTRY");
+ for (int i = 0; i < params.length; i++) {
+ msgBuffer.append(" {").append(i).append("}");
+ }
+ msg = msgBuffer.toString();
+ }
+ LogRecord record = new LogRecord(Level.FINER, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(params);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -815,14 +821,16 @@
* the method name.
*/
public void exiting(String sourceClass, String sourceMethod) {
- if (internalIsLoggable(Level.FINER)) {
- LogRecord record = new LogRecord(Level.FINER, "RETURN"); //$NON-NLS-1$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(Level.FINER)) {
+ return;
}
+
+ LogRecord record = new LogRecord(Level.FINER, "RETURN"); //$NON-NLS-1$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -838,15 +846,17 @@
* the return value of the method call.
*/
public void exiting(String sourceClass, String sourceMethod, Object result) {
- if (internalIsLoggable(Level.FINER)) {
- LogRecord record = new LogRecord(Level.FINER, "RETURN" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { result });
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(Level.FINER)) {
+ return;
}
+
+ LogRecord record = new LogRecord(Level.FINER, "RETURN" + " {0}"); //$NON-NLS-1$ //$NON-NLS-2$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { result });
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -864,15 +874,17 @@
*/
public void throwing(String sourceClass, String sourceMethod,
Throwable thrown) {
- if (internalIsLoggable(Level.FINER)) {
- LogRecord record = new LogRecord(Level.FINER, "THROW"); //$NON-NLS-1$
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setThrown(thrown);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(Level.FINER)) {
+ return;
}
+
+ LogRecord record = new LogRecord(Level.FINER, "THROW"); //$NON-NLS-1$
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setThrown(thrown);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -883,12 +895,7 @@
* the message to log.
*/
public void severe(String msg) {
- if (internalIsLoggable(Level.SEVERE)) {
- LogRecord record = new LogRecord(Level.SEVERE, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
+ log(Level.SEVERE, msg);
}
/**
@@ -899,12 +906,7 @@
* the message to log.
*/
public void warning(String msg) {
- if (internalIsLoggable(Level.WARNING)) {
- LogRecord record = new LogRecord(Level.WARNING, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
+ log(Level.WARNING, msg);
}
/**
@@ -915,12 +917,7 @@
* the message to log.
*/
public void info(String msg) {
- if (internalIsLoggable(Level.INFO)) {
- LogRecord record = new LogRecord(Level.INFO, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
+ log(Level.INFO, msg);
}
/**
@@ -931,12 +928,7 @@
* the message to log.
*/
public void config(String msg) {
- if (internalIsLoggable(Level.CONFIG)) {
- LogRecord record = new LogRecord(Level.CONFIG, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
+ log(Level.CONFIG, msg);
}
/**
@@ -947,12 +939,7 @@
* the message to log.
*/
public void fine(String msg) {
- if (internalIsLoggable(Level.FINE)) {
- LogRecord record = new LogRecord(Level.FINE, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
+ log(Level.FINE, msg);
}
/**
@@ -963,12 +950,7 @@
* the message to log.
*/
public void finer(String msg) {
- if (internalIsLoggable(Level.FINER)) {
- LogRecord record = new LogRecord(Level.FINER, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
+ log(Level.FINER, msg);
}
/**
@@ -979,12 +961,7 @@
* the message to log.
*/
public void finest(String msg) {
- if (internalIsLoggable(Level.FINEST)) {
- LogRecord record = new LogRecord(Level.FINEST, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
- }
+ log(Level.FINEST, msg);
}
/**
@@ -997,12 +974,13 @@
* the message to log.
*/
public void log(Level logLevel, String msg) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ // BEGIN android-only
+ dalvikLogHandler.publish(this, androidTag, logLevel, msg);
+ // END android-only
}
/**
@@ -1017,13 +995,15 @@
* the parameter associated with the event that is logged.
*/
public void log(Level logLevel, String msg, Object param) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setParameters(new Object[] { param });
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setParameters(new Object[] { param });
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -1038,13 +1018,15 @@
* the parameter array associated with the event that is logged.
*/
public void log(Level logLevel, String msg, Object[] params) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setParameters(params);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setParameters(params);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -1060,13 +1042,15 @@
* logged.
*/
public void log(Level logLevel, String msg, Throwable thrown) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setThrown(thrown);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setThrown(thrown);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -1085,31 +1069,33 @@
* the log record to be logged.
*/
public void log(LogRecord record) {
- if (internalIsLoggable(record.getLevel())) {
- // apply the filter if any
- Filter f = filter;
- if (null != f && !f.isLoggable(record)) {
- return;
- }
- initHandler();
- /*
- * call the handlers of this logger, throw any exception that occurs
- */
- Handler[] allHandlers = getHandlers();
- for (Handler element : allHandlers) {
+ if (!internalIsLoggable(record.getLevel())) {
+ return;
+ }
+
+ // apply the filter if any
+ Filter f = filter;
+ if (f != null && !f.isLoggable(record)) {
+ return;
+ }
+
+ /*
+ * call the handlers of this logger, throw any exception that occurs
+ */
+ Handler[] allHandlers = getHandlers();
+ for (Handler element : allHandlers) {
+ element.publish(record);
+ }
+ // call the parent's handlers if set useParentHandlers
+ Logger temp = this;
+ Logger theParent = temp.parent;
+ while (theParent != null && temp.getUseParentHandlers()) {
+ Handler[] ha = theParent.getHandlers();
+ for (Handler element : ha) {
element.publish(record);
}
- // call the parent's handlers if set useParentHandlers
- Logger temp = this;
- Logger theParent = temp.parent;
- while (theParent != null && temp.getUseParentHandlers()) {
- Handler[] ha = theParent.getHandlers();
- for (Handler element : ha) {
- element.publish(record);
- }
- temp = theParent;
- theParent = temp.parent;
- }
+ temp = theParent;
+ theParent = temp.parent;
}
}
@@ -1128,14 +1114,16 @@
*/
public void logp(Level logLevel, String sourceClass, String sourceMethod,
String msg) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -1155,15 +1143,17 @@
*/
public void logp(Level logLevel, String sourceClass, String sourceMethod,
String msg, Object param) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { param });
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { param });
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -1183,15 +1173,17 @@
*/
public void logp(Level logLevel, String sourceClass, String sourceMethod,
String msg, Object[] params) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(params);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(params);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -1211,15 +1203,17 @@
*/
public void logp(Level logLevel, String sourceClass, String sourceMethod,
String msg, Throwable thrown) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setThrown(thrown);
- setResourceBundle(record);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setThrown(thrown);
+ setResourceBundle(record);
+ log(record);
}
/**
@@ -1241,21 +1235,23 @@
*/
public void logrb(Level logLevel, String sourceClass, String sourceMethod,
String bundleName, String msg) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- if (null != bundleName) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (bundleName != null) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ log(record);
}
/**
@@ -1279,22 +1275,24 @@
*/
public void logrb(Level logLevel, String sourceClass, String sourceMethod,
String bundleName, String msg, Object param) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- if (null != bundleName) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(new Object[] { param });
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (bundleName != null) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(new Object[] { param });
+ log(record);
}
/**
@@ -1318,22 +1316,24 @@
*/
public void logrb(Level logLevel, String sourceClass, String sourceMethod,
String bundleName, String msg, Object[] params) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- if (null != bundleName) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setParameters(params);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (bundleName != null) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setParameters(params);
+ log(record);
}
/**
@@ -1357,22 +1357,24 @@
*/
public void logrb(Level logLevel, String sourceClass, String sourceMethod,
String bundleName, String msg, Throwable thrown) {
- if (internalIsLoggable(logLevel)) {
- LogRecord record = new LogRecord(logLevel, msg);
- if (null != bundleName) {
- try {
- record.setResourceBundle(loadResourceBundle(bundleName));
- } catch (MissingResourceException e) {
- // ignore
- }
- record.setResourceBundleName(bundleName);
- }
- record.setLoggerName(this.name);
- record.setSourceClassName(sourceClass);
- record.setSourceMethodName(sourceMethod);
- record.setThrown(thrown);
- log(record);
+ if (!internalIsLoggable(logLevel)) {
+ return;
}
+
+ LogRecord record = new LogRecord(logLevel, msg);
+ if (bundleName != null) {
+ try {
+ record.setResourceBundle(loadResourceBundle(bundleName));
+ } catch (MissingResourceException e) {
+ // ignore
+ }
+ record.setResourceBundleName(bundleName);
+ }
+ record.setLoggerName(this.name);
+ record.setSourceClassName(sourceClass);
+ record.setSourceMethodName(sourceMethod);
+ record.setThrown(thrown);
+ log(record);
}
/*
@@ -1384,42 +1386,19 @@
}
}
- void setManager(LogManager manager) {
- if (this.manager != manager) {
- this.manager = manager;
- handlerInited = false;
- }
- // init level here, but let handlers be for lazy loading
- final String configedLevel = manager.getProperty(name + ".level"); //$NON-NLS-1$
- if (null != configedLevel) {
- try {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- setLevel(Level.parse(configedLevel));
- return null;
- }
- });
- } catch (IllegalArgumentException e) {
- // ignore
- }
- }
- }
-
- synchronized void reset() {
+ void reset() {
levelObjVal = null;
levelIntVal = Level.INFO.intValue();
- if (handlers != null) {
- for (Handler element : handlers) {
- // close all handlers, when unknown exceptions happen,
- // ignore them and go on
- try {
- element.close();
- } catch (Exception e) {
- // Ignored.
+
+ for (Handler handler : handlers) {
+ try {
+ if (handlers.remove(handler)) {
+ handler.close();
}
+ } catch (Exception ignored) {
}
- handlers.clear();
}
- handlerInited = false;
+
+ updateDalvikLogHandler(); // android-only
}
}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
index 3ff1fc9..e4ef413 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
@@ -50,6 +50,7 @@
import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+import tests.util.TestEnvironment;
/**
*/
@@ -62,18 +63,11 @@
final static String className = FileHandlerTest.class.getName();
- final static StringWriter writer = new StringWriter();
-
- final static SecurityManager securityManager = new MockLogSecurityManager();
-
final static String SEP = File.separator;
- private String oldHomePath = System.getProperty("user.home");
-
- // The HOMEPATH can't be used in android.
- final static String HOMEPATH = System.getProperty("java.io.tmpdir") + SEP + "home";
+ String HOMEPATH;
- final static String TEMPPATH = System.getProperty("java.io.tmpdir");
+ String TEMPPATH;
private final PrintStream err = System.err;
@@ -88,6 +82,7 @@
*/
protected void setUp() throws Exception {
super.setUp();
+ TestEnvironment.reset();
manager.reset();
//initProp
@@ -106,19 +101,10 @@
props.put("java.util.logging.FileHandler.append", "true");
props.put("java.util.logging.FileHandler.pattern",
"%t/log/java%u.test");
-
- File home = new File(HOMEPATH);
- if (!home.exists()) {
- home.mkdirs();
- } else if (!home.isDirectory()) {
- home.delete();
- home.mkdirs();
- }
- if(!home.isDirectory()) {
- fail("unable to create temp path");
- }
- System.setProperty("user.home", HOMEPATH);
-
+
+ HOMEPATH = System.getProperty("user.home");
+ TEMPPATH = System.getProperty("java.io.tmpdir");
+
File file = new File(TEMPPATH + SEP + "log");
file.mkdir();
manager.readConfiguration(EnvironmentHelper
@@ -140,8 +126,7 @@
}
reset(TEMPPATH + SEP + "log", "");
System.setErr(err);
- System.setProperty("user.home", oldHomePath);
- new File(HOMEPATH).delete();
+ TestEnvironment.reset();
super.tearDown();
}
@@ -634,8 +619,6 @@
assertFileContent(TEMPPATH, "testLimitCount0.0",
new LogRecord[] { rs[9] }, handler.getFormatter());
- String oldUserDir = System.getProperty("user.dir");
- System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
FileHandler h1 = null;
FileHandler h2 = null;
try {
@@ -656,7 +639,6 @@
} catch (Exception e) {
}
reset("log", "");
- System.setProperty("user.dir", oldUserDir);
}
}
@TestTargets({
@@ -1000,14 +982,6 @@
fail("should throw IllegalArgumentException");
} catch (IllegalArgumentException e) {
}
-
- // always parse special pattern
- System.setProperty("user.home", "home");
- try {
- h1 = new FileHandler("%t/%h.txt");
- } catch (Exception e) {
- fail("Unexpected exception " + e.toString());
- }
}
/*
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
index cf608bc..3083dc9 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
@@ -45,6 +45,7 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import tests.util.TestEnvironment;
/**
*
@@ -107,6 +108,7 @@
*/
@Override
protected void tearDown() throws Exception {
+ TestEnvironment.reset();
super.tearDown();
handler = null;
}
@@ -835,6 +837,16 @@
assertNull(m.getProperty("java.util.logging.FileHandler.pattern"));
}
+ public void testReadConfiguration() throws SecurityException,
+ IOException {
+
+ MockConfigLogManager lm = new MockConfigLogManager();
+ assertFalse(lm.isCalled);
+
+ lm.readConfiguration();
+ assertTrue(lm.isCalled);
+ }
+
private static void checkProperty(LogManager m) {
// assertEquals(m.getProperty(".level"), "INFO");
assertEquals(m.getProperty("java.util.logging.FileHandler.limit"), "50000");
@@ -1194,24 +1206,17 @@
args = {}
)
public void testValidConfigClass() throws Exception {
- String oldProperty = System.getProperty("java.util.logging.config.class");
- try {
- // System.setProperty("java.util.logging.config.class", "org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$ConfigClass");
- System.setProperty("java.util.logging.config.class", this.getClass().getName()
- + "$ConfigClass");
- assertNull(manager.getLogger("testConfigClass.foo"));
+ // System.setProperty("java.util.logging.config.class", "org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$ConfigClass");
+ System.setProperty("java.util.logging.config.class", this.getClass().getName()
+ + "$ConfigClass");
+ assertNull(manager.getLogger("testConfigClass.foo"));
- manager.readConfiguration();
- assertNull(manager.getLogger("testConfigClass.foo"));
- Logger l = Logger.getLogger("testConfigClass.foo.child");
- assertSame(Level.FINEST, manager.getLogger("").getLevel());
- assertEquals(0, manager.getLogger("").getHandlers().length);
- assertEquals("testConfigClass.foo", l.getParent().getName());
- } finally {
- if (oldProperty != null) {
- System.setProperty("java.util.logging.config.class", oldProperty);
- }
- }
+ manager.readConfiguration();
+ assertNull(manager.getLogger("testConfigClass.foo"));
+ Logger l = Logger.getLogger("testConfigClass.foo.child");
+ assertSame(Level.FINEST, manager.getLogger("").getLevel());
+ assertEquals(0, manager.getLogger("").getHandlers().length);
+ assertEquals("testConfigClass.foo", l.getParent().getName());
}
/*
@@ -1368,6 +1373,15 @@
public static class MockLogManager extends LogManager {
}
+ public static class MockConfigLogManager extends LogManager {
+ public boolean isCalled = false;
+
+ public void readConfiguration(InputStream ins) throws IOException {
+ isCalled = true;
+ super.readConfiguration(ins);
+ }
+ }
+
public static class MockHandler extends Handler {
static int number = 0;
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
index 5b21099..6d4f784 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
@@ -295,7 +295,7 @@
assertNull(lr.getSourceClassName());
// find class and method who called logger
- Logger logger = Logger.global;
+ Logger logger = Logger.getLogger("testGetSourceDefaultValue");
MockHandler handler = new MockHandler();
logger.addHandler(handler);
logger.log(Level.SEVERE, MSG);
diff --git a/luni-kernel/src/main/java/java/lang/Package.java b/luni-kernel/src/main/java/java/lang/Package.java
index 2817404..4d98959 100644
--- a/luni-kernel/src/main/java/java/lang/Package.java
+++ b/luni-kernel/src/main/java/java/lang/Package.java
@@ -268,8 +268,8 @@
*/
public boolean isCompatibleWith(String version)
throws NumberFormatException {
- String[] requested = version.split(".");
- String[] provided = specVersion.split(".");
+ String[] requested = version.split("\\.");
+ String[] provided = specVersion.split("\\.");
for (int i = 0; i < Math.min(requested.length, provided.length); i++) {
int reqNum = Integer.parseInt(requested[i]);
@@ -318,4 +318,3 @@
return "package " + name;
}
}
-
diff --git a/luni-kernel/src/main/java/java/lang/ProcessManager.java b/luni-kernel/src/main/java/java/lang/ProcessManager.java
index 1e21b57..318fe9a 100644
--- a/luni-kernel/src/main/java/java/lang/ProcessManager.java
+++ b/luni-kernel/src/main/java/java/lang/ProcessManager.java
@@ -169,15 +169,45 @@
* Executes a native process. Fills in in, out, and err and returns the
* new process ID upon success.
*/
- static native int exec(String[] commands, String[] environment,
+ static native int exec(String[] command, String[] environment,
String workingDirectory, FileDescriptor in, FileDescriptor out,
- FileDescriptor err) throws IOException;
+ FileDescriptor err, boolean redirectErrorStream) throws IOException;
/**
* Executes a process and returns an object representing it.
*/
- Process exec(String[] commands, String[] environment,
- File workingDirectory) throws IOException {
+ Process exec(String[] taintedCommand, String[] taintedEnvironment, File workingDirectory,
+ boolean redirectErrorStream) throws IOException {
+ // Make sure we throw the same exceptions as the RI.
+ if (taintedCommand == null) {
+ throw new NullPointerException();
+ }
+ if (taintedCommand.length == 0) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ // Handle security and safety by copying mutable inputs and checking them.
+ String[] command = taintedCommand.clone();
+ String[] environment = taintedEnvironment != null ? taintedEnvironment.clone() : null;
+ SecurityManager securityManager = System.getSecurityManager();
+ if (securityManager != null) {
+ securityManager.checkExec(command[0]);
+ }
+ // Check we're not passing null Strings to the native exec.
+ for (String arg : command) {
+ if (arg == null) {
+ throw new NullPointerException();
+ }
+ }
+ // The environment is allowed to be null or empty, but no element may be null.
+ if (environment != null) {
+ for (String env : environment) {
+ if (env == null) {
+ throw new NullPointerException();
+ }
+ }
+ }
+
FileDescriptor in = new FileDescriptor();
FileDescriptor out = new FileDescriptor();
FileDescriptor err = new FileDescriptor();
@@ -191,10 +221,10 @@
synchronized (processReferences) {
int pid;
try {
- pid = exec(commands, environment, workingPath, in, out, err);
+ pid = exec(command, environment, workingPath, in, out, err, redirectErrorStream);
} catch (IOException e) {
IOException wrapper = new IOException("Error running exec()."
- + " Commands: " + Arrays.toString(commands)
+ + " Command: " + Arrays.toString(command)
+ " Working Directory: " + workingDirectory
+ " Environment: " + Arrays.toString(environment));
wrapper.initCause(e);
diff --git a/luni-kernel/src/main/java/java/lang/Runtime.java b/luni-kernel/src/main/java/java/lang/Runtime.java
index 28cc96f..8560399 100644
--- a/luni-kernel/src/main/java/java/lang/Runtime.java
+++ b/luni-kernel/src/main/java/java/lang/Runtime.java
@@ -190,39 +190,11 @@
* execution.
* @see SecurityManager#checkExec
* @since Android 1.0
- */
- public Process exec(String[] progArray, String[] envp, File directory)
- throws java.io.IOException {
-
- // Sanity checks
- if (progArray == null) {
- throw new NullPointerException();
- } else if (progArray.length == 0) {
- throw new IndexOutOfBoundsException();
- } else {
- for (int i = 0; i < progArray.length; i++) {
- if (progArray[i] == null) {
- throw new NullPointerException();
- }
- }
- }
-
- if (envp != null) {
- for (int i = 0; i < envp.length; i++) {
- if (envp[i] == null) {
- throw new NullPointerException();
- }
- }
- }
-
- // Security checks
- SecurityManager smgr = System.getSecurityManager();
- if (smgr != null) {
- smgr.checkExec(progArray[0]);
- }
-
- // Delegate the execution
- return ProcessManager.getInstance().exec(progArray, envp, directory);
+ */
+ public Process exec(String[] progArray, String[] envp, File directory) throws IOException {
+ // BEGIN android-changed: push responsibility for argument checking into ProcessManager
+ return ProcessManager.getInstance().exec(progArray, envp, directory, false);
+ // END android-changed
}
/**
diff --git a/luni-kernel/src/main/java/java/lang/ref/Reference.java b/luni-kernel/src/main/java/java/lang/ref/Reference.java
index ca7290b..c695830 100644
--- a/luni-kernel/src/main/java/java/lang/ref/Reference.java
+++ b/luni-kernel/src/main/java/java/lang/ref/Reference.java
@@ -49,7 +49,7 @@
* VM requirement: this field <em>must</em> be called "referent"
* and be an object.
*/
- T referent;
+ volatile T referent;
/**
* If non-null, the queue on which this reference will be enqueued
@@ -58,7 +58,7 @@
* and be a java.lang.ref.ReferenceQueue.
*/
@SuppressWarnings("unchecked")
- ReferenceQueue queue;
+ volatile ReferenceQueue queue;
/**
* Used internally by java.lang.ref.ReferenceQueue.
@@ -66,7 +66,7 @@
* and be a java.lang.ref.Reference.
*/
@SuppressWarnings("unchecked")
- Reference queueNext;
+ volatile Reference queueNext;
/**
* Used internally by Dalvik.
@@ -74,7 +74,7 @@
* and be an int.
*/
@SuppressWarnings("unused")
- private int vmData;
+ volatile private int vmData;
/**
* Constructs a new instance of this class.
diff --git a/luni-kernel/src/main/java/java/lang/reflect/Constructor.java b/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
index c6927eb..3918d7e 100644
--- a/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
+++ b/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
@@ -161,12 +161,12 @@
appendArrayGenericType(sb,
Types.getClonedTypeArray(genericParameterTypes));
sb.append(')');
- // append exeptions if any
- Type[] genericEceptionTypeArray =
+ // append exceptions if any
+ Type[] genericExceptionTypeArray =
Types.getClonedTypeArray(genericExceptionTypes);
- if (genericEceptionTypeArray.length > 0) {
+ if (genericExceptionTypeArray.length > 0) {
sb.append(" throws ");
- appendArrayGenericType(sb, genericEceptionTypeArray);
+ appendArrayGenericType(sb, genericExceptionTypeArray);
}
return sb.toString();
}
@@ -314,7 +314,7 @@
public Class<?>[] getExceptionTypes() {
if (exceptionTypes == null)
return new Class[0];
- return exceptionTypes;
+ return exceptionTypes.clone();
}
/**
@@ -354,7 +354,7 @@
* @since Android 1.0
*/
public Class<?>[] getParameterTypes() {
- return parameterTypes;
+ return parameterTypes.clone();
}
/**
diff --git a/luni-kernel/src/main/java/java/lang/reflect/Method.java b/luni-kernel/src/main/java/java/lang/reflect/Method.java
index 473726d..dabf9a4 100644
--- a/luni-kernel/src/main/java/java/lang/reflect/Method.java
+++ b/luni-kernel/src/main/java/java/lang/reflect/Method.java
@@ -383,7 +383,7 @@
return new Class[0];
}
- return exceptionTypes;
+ return exceptionTypes.clone();
}
/**
@@ -424,7 +424,7 @@
* @since Android 1.0
*/
public Class<?>[] getParameterTypes() {
- return parameterTypes;
+ return parameterTypes.clone();
}
/**
@@ -521,7 +521,7 @@
return invokeNative (receiver, args, declaringClass, parameterTypes, returnType, slot, flag);
}
- private native Object invokeNative(Object obj, Object[] args, Class<?> declaringClass, Class<?>[] parameterTYpes, Class<?> returnType, int slot, boolean noAccessCheck)
+ private native Object invokeNative(Object obj, Object[] args, Class<?> declaringClass, Class<?>[] parameterTypes, Class<?> returnType, int slot, boolean noAccessCheck)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException;
diff --git a/luni-kernel/src/main/native/java_lang_ProcessManager.c b/luni-kernel/src/main/native/java_lang_ProcessManager.cpp
similarity index 81%
rename from luni-kernel/src/main/native/java_lang_ProcessManager.c
rename to luni-kernel/src/main/native/java_lang_ProcessManager.cpp
index eaefc9f..045d980 100644
--- a/luni-kernel/src/main/native/java_lang_ProcessManager.c
+++ b/luni-kernel/src/main/native/java_lang_ProcessManager.cpp
@@ -51,21 +51,11 @@
#define WAIT_STATUS_STRANGE_ERRNO (-3) // observed an undocumented errno
/** Closes a file descriptor. */
-static int closeNow(int fd) {
- int result;
- do {
- result = close(fd);
- } while (result == -1 && errno == EINTR);
- return result;
-}
-
-/** Closes a file descriptor. */
static void java_lang_ProcessManager_close(JNIEnv* env,
- jclass clazz, jobject javaDescriptor) {
- int fd = (*env)->GetIntField(env, javaDescriptor, descriptorField);
- if (closeNow(fd) == -1) {
- jclass ioException = (*env)->FindClass(env, "java/io/IOException");
- (*env)->ThrowNew(env, ioException, strerror(errno));
+ jclass, jobject javaDescriptor) {
+ int fd = env->GetIntField(javaDescriptor, descriptorField);
+ if (TEMP_FAILURE_RETRY(close(fd)) == -1) {
+ jniThrowIOException(env, errno);
}
}
@@ -144,9 +134,8 @@
}
}
- (*env)->CallVoidMethod(env, o, onExitMethod, pid, status);
-
- if ((*env)->ExceptionOccurred(env)) {
+ env->CallVoidMethod(o, onExitMethod, pid, status);
+ if (env->ExceptionOccurred()) {
/*
* The callback threw, so break out of the loop and return,
* letting the exception percolate up.
@@ -158,11 +147,11 @@
/** Close all open fds > 2 (i.e. everything but stdin/out/err), != skipFd. */
static void closeNonStandardFds(int skipFd) {
+ // TODO: rather than close all these non-open files, we could look in /proc/self/fd.
struct rlimit rlimit;
getrlimit(RLIMIT_NOFILE, &rlimit);
-
- int fd;
- for (fd = 3; fd < rlimit.rlim_max; fd++) {
+ const int max_fd = rlimit.rlim_max;
+ for (int fd = 3; fd < max_fd; ++fd) {
if (fd != skipFd
#ifdef ANDROID
&& fd != androidSystemPropertiesFd
@@ -192,7 +181,8 @@
/** Executes a command in a child process. */
static pid_t executeProcess(JNIEnv* env, char** commands, char** environment,
const char* workingDirectory, jobject inDescriptor,
- jobject outDescriptor, jobject errDescriptor) {
+ jobject outDescriptor, jobject errDescriptor,
+ jboolean redirectErrorStream) {
int i, result, error;
// Create 4 pipes: stdin, stdout, stderr, and an exec() status pipe.
@@ -233,7 +223,11 @@
// Replace stdin, out, and err with pipes.
dup2(stdinIn, 0);
dup2(stdoutOut, 1);
- dup2(stderrOut, 2);
+ if (redirectErrorStream) {
+ dup2(stdoutOut, 2);
+ } else {
+ dup2(stderrOut, 2);
+ }
// Close all but statusOut. This saves some work in the next step.
closePipes(pipes, statusOut);
@@ -307,15 +301,14 @@
}
char** array = NULL;
- jsize length = (*env)->GetArrayLength(env, javaArray);
+ jsize length = env->GetArrayLength(javaArray);
array = (char**) malloc(sizeof(char*) * (length + 1));
array[length] = 0;
jsize index;
for (index = 0; index < length; index++) {
- jstring javaEntry = (jstring) (*env)->GetObjectArrayElement(
- env, javaArray, index);
- char* entry = (char*) (*env)->GetStringUTFChars(
- env, javaEntry, NULL);
+ jstring javaEntry =
+ (jstring) env->GetObjectArrayElement(javaArray, index);
+ char* entry = (char*) env->GetStringUTFChars(javaEntry, NULL);
array[index] = entry;
}
@@ -328,12 +321,12 @@
return;
}
- jsize length = (*env)->GetArrayLength(env, javaArray);
+ jsize length = env->GetArrayLength(javaArray);
jsize index;
for (index = 0; index < length; index++) {
- jstring javaEntry = (jstring) (*env)->GetObjectArrayElement(
- env, javaArray, index);
- (*env)->ReleaseStringUTFChars(env, javaEntry, array[index]);
+ jstring javaEntry =
+ (jstring) env->GetObjectArrayElement(javaArray, index);
+ env->ReleaseStringUTFChars(javaEntry, array[index]);
}
free(array);
@@ -345,7 +338,8 @@
static pid_t java_lang_ProcessManager_exec(
JNIEnv* env, jclass clazz, jobjectArray javaCommands,
jobjectArray javaEnvironment, jstring javaWorkingDirectory,
- jobject inDescriptor, jobject outDescriptor, jobject errDescriptor) {
+ jobject inDescriptor, jobject outDescriptor, jobject errDescriptor,
+ jboolean redirectErrorStream) {
// Copy commands into char*[].
char** commands = convertStrings(env, javaCommands);
@@ -353,8 +347,7 @@
// Extract working directory string.
const char* workingDirectory = NULL;
if (javaWorkingDirectory != NULL) {
- workingDirectory = (const char*) (*env)->GetStringUTFChars(
- env, javaWorkingDirectory, NULL);
+ workingDirectory = env->GetStringUTFChars(javaWorkingDirectory, NULL);
}
// Convert environment array.
@@ -362,25 +355,24 @@
pid_t result = executeProcess(
env, commands, environment, workingDirectory,
- inDescriptor, outDescriptor, errDescriptor);
+ inDescriptor, outDescriptor, errDescriptor, redirectErrorStream);
// Temporarily clear exception so we can clean up.
- jthrowable exception = (*env)->ExceptionOccurred(env);
- (*env)->ExceptionClear(env);
+ jthrowable exception = env->ExceptionOccurred();
+ env->ExceptionClear();
freeStrings(env, javaEnvironment, environment);
// Clean up working directory string.
if (javaWorkingDirectory != NULL) {
- (*env)->ReleaseStringUTFChars(
- env, javaWorkingDirectory, workingDirectory);
+ env->ReleaseStringUTFChars(javaWorkingDirectory, workingDirectory);
}
freeStrings(env, javaCommands, commands);
// Re-throw exception if present.
if (exception != NULL) {
- if ((*env)->Throw(env, exception) < 0) {
+ if (env->Throw(exception) < 0) {
LOGE("Error rethrowing exception!");
}
}
@@ -400,33 +392,28 @@
}
#endif
- onExitMethod = (*env)->GetMethodID(env, clazz, "onExit", "(II)V");
+ onExitMethod = env->GetMethodID(clazz, "onExit", "(II)V");
if (onExitMethod == NULL) {
return;
}
- jclass fileDescriptorClass
- = (*env)->FindClass(env, "java/io/FileDescriptor");
+ jclass fileDescriptorClass = env->FindClass("java/io/FileDescriptor");
if (fileDescriptorClass == NULL) {
return;
}
- descriptorField = (*env)->GetFieldID(env, fileDescriptorClass,
- "descriptor", "I");
+ descriptorField = env->GetFieldID(fileDescriptorClass, "descriptor", "I");
if (descriptorField == NULL) {
return;
}
}
static JNINativeMethod methods[] = {
- { "kill", "(I)V", (void*) java_lang_ProcessManager_kill },
- { "watchChildren", "()V", (void*) java_lang_ProcessManager_watchChildren },
- { "exec", "([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;"
- "Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;"
- "Ljava/io/FileDescriptor;)I", (void*) java_lang_ProcessManager_exec },
- { "staticInitialize", "()V",
- (void*) java_lang_ProcessManager_staticInitialize },
- { "close", "(Ljava/io/FileDescriptor;)V",
- (void*) java_lang_ProcessManager_close },
+ { "close", "(Ljava/io/FileDescriptor;)V", (void*) java_lang_ProcessManager_close },
+ { "kill", "(I)V", (void*) java_lang_ProcessManager_kill },
+ { "staticInitialize", "()V", (void*) java_lang_ProcessManager_staticInitialize },
+ { "watchChildren", "()V", (void*) java_lang_ProcessManager_watchChildren },
+ { "exec", "([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Z)I",
+ (void*) java_lang_ProcessManager_exec },
};
int register_java_lang_ProcessManager(JNIEnv* env) {
diff --git a/luni-kernel/src/main/native/java_lang_System.c b/luni-kernel/src/main/native/java_lang_System.c
deleted file mode 100644
index 1c06a40..0000000
--- a/luni-kernel/src/main/native/java_lang_System.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNIHelp.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-
-/*
- * public static native String getEnvByName(String name)
- *
- * (Calling it plain "getenv" might confuse GDB if you try to put a breakpoint
- * on the libc version.)
- */
-static jstring java_getEnvByName(JNIEnv* env, jclass clazz, jstring nameStr)
-{
- jstring valueStr = NULL;
-
- if (nameStr != NULL) {
- const char* name;
- const char* val;
-
- name = (*env)->GetStringUTFChars(env, nameStr, NULL);
- val = getenv(name);
- if (val != NULL)
- valueStr = (*env)->NewStringUTF(env, val);
-
- (*env)->ReleaseStringUTFChars(env, nameStr, name);
- } else {
- jniThrowException(env, "java/lang/NullPointerException", NULL);
- }
-
- return valueStr;
-}
-
-/*
- * Pointer to complete environment, from Posix.
- */
-extern char** environ;
-
-/*
- * public static native String getEnvByIndex()
- *
- * (Calling it plain "getenv" might confuse GDB if you try to put a breakpoint
- * on the libc version.)
- */
-static jstring java_getEnvByIndex(JNIEnv* env, jclass clazz, jint index)
-{
- jstring valueStr = NULL;
-
- char* entry = environ[index];
- if (entry != NULL) {
- valueStr = (*env)->NewStringUTF(env, entry);
- }
-
- return valueStr;
-}
-
-/*
- * public static native String setFieldImpl()
- *
- * Sets a field via JNI. Used for the standard streams, which are r/o
- * otherwise.
- */
-static void java_setFieldImpl(JNIEnv* env, jclass clazz, jstring name, jstring sig, jobject object)
-{
- const char* fieldName = (*env)->GetStringUTFChars(env, name, NULL);
- const char* fieldSig = (*env)->GetStringUTFChars(env, sig, NULL);
-
- jfieldID fieldID = (*env)->GetStaticFieldID(env, clazz, fieldName, fieldSig);
- (*env)->SetStaticObjectField(env, clazz, fieldID, object);
-
- (*env)->ReleaseStringUTFChars(env, name, fieldName);
- (*env)->ReleaseStringUTFChars(env, sig, fieldSig);
-}
-
-/*
- * JNI registration
- */
-static JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "getEnvByName", "(Ljava/lang/String;)Ljava/lang/String;", java_getEnvByName },
- { "getEnvByIndex", "(I)Ljava/lang/String;", java_getEnvByIndex },
- { "setFieldImpl", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", java_setFieldImpl },
-};
-
-int register_java_lang_System(JNIEnv* env)
-{
- return jniRegisterNativeMethods(env, "java/lang/System",
- gMethods, NELEM(gMethods));
-}
-
diff --git a/luni-kernel/src/main/native/java_lang_System.cpp b/luni-kernel/src/main/native/java_lang_System.cpp
new file mode 100644
index 0000000..d02481c
--- /dev/null
+++ b/luni-kernel/src/main/native/java_lang_System.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AndroidSystemNatives.h"
+#include "JNIHelp.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ * public static native String getEnvByName(String name)
+ *
+ * (Calling it plain "getenv" might confuse GDB if you try to put a breakpoint
+ * on the libc version.)
+ */
+static jstring java_getEnvByName(JNIEnv* env, jclass, jstring nameStr) {
+ jstring valueStr = NULL;
+
+ if (nameStr != NULL) {
+ const char* name = env->GetStringUTFChars(nameStr, NULL);
+ const char* val = getenv(name);
+ if (val != NULL) {
+ valueStr = env->NewStringUTF(val);
+ }
+ env->ReleaseStringUTFChars(nameStr, name);
+ } else {
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
+ }
+
+ return valueStr;
+}
+
+/*
+ * Pointer to complete environment, from Posix.
+ */
+extern char** environ;
+
+/*
+ * public static native String getEnvByIndex()
+ *
+ * (Calling it plain "getenv" might confuse GDB if you try to put a breakpoint
+ * on the libc version.)
+ */
+static jstring java_getEnvByIndex(JNIEnv* env, jclass, jint index) {
+ jstring valueStr = NULL;
+
+ char* entry = environ[index];
+ if (entry != NULL) {
+ valueStr = env->NewStringUTF(entry);
+ }
+
+ return valueStr;
+}
+
+/*
+ * public static native String setFieldImpl()
+ *
+ * Sets a field via JNI. Used for the standard streams, which are r/o
+ * otherwise.
+ */
+static void java_setFieldImpl(JNIEnv* env, jclass clazz,
+ jstring name, jstring sig, jobject object) {
+ const char* fieldName = env->GetStringUTFChars(name, NULL);
+ const char* fieldSig = env->GetStringUTFChars(sig, NULL);
+
+ jfieldID fieldID = env->GetStaticFieldID(clazz, fieldName, fieldSig);
+ env->SetStaticObjectField(clazz, fieldID, object);
+
+ env->ReleaseStringUTFChars(name, fieldName);
+ env->ReleaseStringUTFChars(sig, fieldSig);
+}
+
+/*
+ * JNI registration
+ */
+static JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ { "getEnvByName", "(Ljava/lang/String;)Ljava/lang/String;", (void*) java_getEnvByName },
+ { "getEnvByIndex", "(I)Ljava/lang/String;", (void*) java_getEnvByIndex },
+ { "setFieldImpl", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", (void*) java_setFieldImpl },
+};
+
+int register_java_lang_System(JNIEnv* env) {
+ return jniRegisterNativeMethods(env, "java/lang/System",
+ gMethods, NELEM(gMethods));
+}
diff --git a/luni-kernel/src/main/native/sub.mk b/luni-kernel/src/main/native/sub.mk
index cd4ce92..fcb7d0d 100644
--- a/luni-kernel/src/main/native/sub.mk
+++ b/luni-kernel/src/main/native/sub.mk
@@ -3,8 +3,8 @@
# or BUILD_*_LIBRARY.
LOCAL_SRC_FILES := \
- java_lang_ProcessManager.c \
- java_lang_System.c
+ java_lang_ProcessManager.cpp \
+ java_lang_System.cpp
LOCAL_C_INCLUDES +=
diff --git a/luni-kernel/src/test/java/java/lang/reflect/AllTests.java b/luni-kernel/src/test/java/java/lang/reflect/AllTests.java
new file mode 100644
index 0000000..7cf1475
--- /dev/null
+++ b/luni-kernel/src/test/java/java/lang/reflect/AllTests.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.reflect;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static final Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(java.lang.reflect.ConstructorTest.class);
+ suite.addTestSuite(java.lang.reflect.MethodTest.class);
+ return suite;
+ }
+}
diff --git a/luni-kernel/src/test/java/java/lang/reflect/ConstructorTest.java b/luni-kernel/src/test/java/java/lang/reflect/ConstructorTest.java
new file mode 100644
index 0000000..e2672a8
--- /dev/null
+++ b/luni-kernel/src/test/java/java/lang/reflect/ConstructorTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.reflect;
+
+public class ConstructorTest extends junit.framework.TestCase {
+ public void test_getExceptionTypes() throws Exception {
+ Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(new Class[0]);
+ Class[] exceptions = constructor.getExceptionTypes();
+ assertEquals(1, exceptions.length);
+ assertEquals(IndexOutOfBoundsException.class, exceptions[0]);
+ // Check that corrupting our array doesn't affect other callers.
+ exceptions[0] = NullPointerException.class;
+ exceptions = constructor.getExceptionTypes();
+ assertEquals(1, exceptions.length);
+ assertEquals(IndexOutOfBoundsException.class, exceptions[0]);
+ }
+
+ public void test_getParameterTypes() throws Exception {
+ Class[] expectedParameters = new Class[] { Object.class };
+ Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(expectedParameters);
+ Class[] parameters = constructor.getParameterTypes();
+ assertEquals(1, parameters.length);
+ assertEquals(expectedParameters[0], parameters[0]);
+ // Check that corrupting our array doesn't affect other callers.
+ parameters[0] = String.class;
+ parameters = constructor.getParameterTypes();
+ assertEquals(1, parameters.length);
+ assertEquals(expectedParameters[0], parameters[0]);
+ }
+
+ static class ConstructorTestHelper {
+ public ConstructorTestHelper() throws IndexOutOfBoundsException { }
+ public ConstructorTestHelper(Object o) { }
+ }
+}
diff --git a/luni-kernel/src/test/java/java/lang/reflect/MethodTest.java b/luni-kernel/src/test/java/java/lang/reflect/MethodTest.java
new file mode 100644
index 0000000..ed41de9
--- /dev/null
+++ b/luni-kernel/src/test/java/java/lang/reflect/MethodTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang.reflect;
+
+public class MethodTest extends junit.framework.TestCase {
+ public void test_getExceptionTypes() throws Exception {
+ Method method = MethodTestHelper.class.getMethod("m1", new Class[0]);
+ Class[] exceptions = method.getExceptionTypes();
+ assertEquals(1, exceptions.length);
+ assertEquals(IndexOutOfBoundsException.class, exceptions[0]);
+ // Check that corrupting our array doesn't affect other callers.
+ exceptions[0] = NullPointerException.class;
+ exceptions = method.getExceptionTypes();
+ assertEquals(1, exceptions.length);
+ assertEquals(IndexOutOfBoundsException.class, exceptions[0]);
+ }
+
+ public void test_getParameterTypes() throws Exception {
+ Class[] expectedParameters = new Class[] { Object.class };
+ Method method = MethodTestHelper.class.getMethod("m2", expectedParameters);
+ Class[] parameters = method.getParameterTypes();
+ assertEquals(1, parameters.length);
+ assertEquals(expectedParameters[0], parameters[0]);
+ // Check that corrupting our array doesn't affect other callers.
+ parameters[0] = String.class;
+ parameters = method.getParameterTypes();
+ assertEquals(1, parameters.length);
+ assertEquals(expectedParameters[0], parameters[0]);
+ }
+
+ static class MethodTestHelper {
+ public void m1() throws IndexOutOfBoundsException { }
+ public void m2(Object o) { }
+ }
+}
diff --git a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java
new file mode 100644
index 0000000..a59cc3e
--- /dev/null
+++ b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.org.apache.harmony.kernel.dalvik;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static final Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(tests.api.org.apache.harmony.kernel.dalvik.ThreadsTest.class);
+ return suite;
+ }
+}
diff --git a/luni/src/main/java/java/io/BufferedOutputStream.java b/luni/src/main/java/java/io/BufferedOutputStream.java
index 6d52dee..8b7c4f5 100644
--- a/luni/src/main/java/java/io/BufferedOutputStream.java
+++ b/luni/src/main/java/java/io/BufferedOutputStream.java
@@ -148,17 +148,16 @@
out.write(buffer, offset, length);
return;
}
-
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // used (offset | length) < 0 instead of (offset < 0) || (length < 0)
- // to safe one operation
- if ((offset | length) < 0 || offset > buffer.length - length) {
- // K002f=Arguments out of bounds
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+
+ if (offset < 0 || offset > buffer.length - length) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
+
}
- // END android-changed
+ if (length < 0) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
+ }
// flush the internal buffer first if we have not enough space left
if (length >= (buf.length - count)) {
diff --git a/luni/src/main/java/java/io/BufferedReader.java b/luni/src/main/java/java/io/BufferedReader.java
index 77f1975..cfdc4aa 100644
--- a/luni/src/main/java/java/io/BufferedReader.java
+++ b/luni/src/main/java/java/io/BufferedReader.java
@@ -17,6 +17,11 @@
package java.io;
+// BEGIN android-note
+// lots of tidying up of implementation, including renaming fields and changing
+// the implementation of read(char[], int, int)
+// END android-note
+
import org.apache.harmony.luni.util.Msg;
// BEGIN android-added
@@ -44,16 +49,36 @@
private Reader in;
+ /**
+ * The characters that can be read and refilled in bulk. We maintain three
+ * indices into this buffer:<pre>
+ * { X X X X X X X X X X X X - - }
+ * ^ ^ ^
+ * | | |
+ * mark pos end</pre>
+ * Pos points to the next readable character. End is one greater than the
+ * last readable character. When {@code pos == end}, the buffer is empty and
+ * must be {@link #fillBuf() filled} before characters can be read.
+ *
+ * <p>Mark is the value pos will be set to on calls to {@link #reset}. Its
+ * value is in the range {@code [0...pos]}. If the mark is {@code -1}, the
+ * buffer cannot be reset.
+ *
+ * <p>MarkLimit limits the distance between the mark and the pos. When this
+ * limit is exceeded, {@link #reset} is permitted (but not required) to
+ * throw an exception. For shorter distances, {@link #reset} shall not throw
+ * (unless the reader is closed).
+ */
private char[] buf;
- private int marklimit = -1;
-
- private int count;
-
- private int markpos = -1;
-
private int pos;
+ private int end;
+
+ private int mark = -1;
+
+ private int markLimit = -1;
+
/**
* Constructs a new BufferedReader on the Reader {@code in}. The
* buffer gets the default size (8 KB).
@@ -66,7 +91,7 @@
this.in = in;
buf = new char[8192];
- // BEGIN android-added
+ // BEGIN android-only
/*
* For Android, we want to discourage the use of this
* constructor (with its arguably too-large default), so we
@@ -79,7 +104,7 @@
"Default buffer size used in BufferedReader " +
"constructor. It would be " +
"better to be explicit if an 8k-char buffer is required.");
- // END android-added
+ // END android-only
}
/**
@@ -120,36 +145,50 @@
}
}
- private int fillbuf() throws IOException {
- if (markpos == -1 || (pos - markpos >= marklimit)) {
- /* Mark position not set or exceeded readlimit */
+ /**
+ * Populates the buffer with data. It is an error to call this method when
+ * the buffer still contains data; ie. if {@code pos < end}.
+ *
+ * @return the number of bytes read into the buffer, or -1 if the end of the
+ * source stream has been reached.
+ */
+ private int fillBuf() throws IOException {
+ // assert(pos == end);
+
+ if (mark == -1 || (pos - mark >= markLimit)) {
+ /* mark isn't set or has exceeded its limit. use the whole buffer */
int result = in.read(buf, 0, buf.length);
if (result > 0) {
- markpos = -1;
+ mark = -1;
pos = 0;
- count = result == -1 ? 0 : result;
+ end = result;
}
return result;
}
- if (markpos == 0 && marklimit > buf.length) {
- /* Increase buffer size to accommodate the readlimit */
+
+ if (mark == 0 && markLimit > buf.length) {
+ /* the only way to make room when mark=0 is by growing the buffer */
int newLength = buf.length * 2;
- if (newLength > marklimit) {
- newLength = marklimit;
+ if (newLength > markLimit) {
+ newLength = markLimit;
}
char[] newbuf = new char[newLength];
System.arraycopy(buf, 0, newbuf, 0, buf.length);
buf = newbuf;
- } else if (markpos > 0) {
- System.arraycopy(buf, markpos, buf, 0, buf.length - markpos);
+ } else if (mark > 0) {
+ /* make room by shifting the buffered data to left mark positions */
+ System.arraycopy(buf, mark, buf, 0, buf.length - mark);
+ pos -= mark;
+ end -= mark;
+ mark = 0;
}
/* Set the new position and mark position */
- pos -= markpos;
- count = markpos = 0;
- int charsread = in.read(buf, pos, buf.length - pos);
- count = charsread == -1 ? pos : pos + charsread;
- return charsread;
+ int count = in.read(buf, pos, buf.length - pos);
+ if (count != -1) {
+ end += count;
+ }
+ return count;
}
/**
@@ -163,32 +202,32 @@
}
/**
- * Sets a mark position in this reader. The parameter {@code readlimit}
+ * Sets a mark position in this reader. The parameter {@code markLimit}
* indicates how many characters can be read before the mark is invalidated.
* Calling {@code reset()} will reposition the reader back to the marked
- * position if {@code readlimit} has not been surpassed.
+ * position if {@code markLimit} has not been surpassed.
*
- * @param readlimit
+ * @param markLimit
* the number of characters that can be read before the mark is
* invalidated.
* @throws IllegalArgumentException
- * if {@code readlimit < 0}.
+ * if {@code markLimit < 0}.
* @throws IOException
* if an error occurs while setting a mark in this reader.
* @see #markSupported()
* @see #reset()
*/
@Override
- public void mark(int readlimit) throws IOException {
- if (readlimit < 0) {
+ public void mark(int markLimit) throws IOException {
+ if (markLimit < 0) {
throw new IllegalArgumentException();
}
synchronized (lock) {
if (isClosed()) {
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
}
- marklimit = readlimit;
- markpos = pos;
+ this.markLimit = markLimit;
+ mark = pos;
}
}
@@ -224,10 +263,9 @@
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
}
/* Are there buffered characters available? */
- if (pos < count || fillbuf() != -1) {
+ if (pos < end || fillBuf() != -1) {
return buf[pos++];
}
- markpos = -1;
return -1;
}
}
@@ -276,52 +314,59 @@
throw new IndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
}
// END android-changed
- if (length == 0) {
- return 0;
- }
- int required;
- if (pos < count) {
- /* There are bytes available in the buffer. */
- int copylength = count - pos >= length ? length : count - pos;
- System.arraycopy(buf, pos, buffer, offset, copylength);
- pos += copylength;
- if (copylength == length || !in.ready()) {
- return copylength;
+
+ int outstanding = length;
+ while (outstanding > 0) {
+
+ /*
+ * If there are bytes in the buffer, grab those first.
+ */
+ int available = end - pos;
+ if (available > 0) {
+ int count = available >= outstanding ? outstanding : available;
+ System.arraycopy(buf, pos, buffer, offset, count);
+ pos += count;
+ offset += count;
+ outstanding -= count;
}
- offset += copylength;
- required = length - copylength;
- } else {
- required = length;
+
+ /*
+ * Before attempting to read from the underlying stream, make
+ * sure we really, really want to. We won't bother if we're
+ * done, or if we've already got some bytes and reading from the
+ * underlying stream would block.
+ */
+ if (outstanding == 0 || (outstanding < length && !in.ready())) {
+ break;
+ }
+
+ // assert(pos == end);
+
+ /*
+ * If we're unmarked and the requested size is greater than our
+ * buffer, read the bytes directly into the caller's buffer. We
+ * don't read into smaller buffers because that could result in
+ * a many reads.
+ */
+ if ((mark == -1 || (pos - mark >= markLimit))
+ && outstanding >= buf.length) {
+ int count = in.read(buffer, offset, outstanding);
+ if (count > 0) {
+ offset += count;
+ outstanding -= count;
+ mark = -1;
+ }
+
+ break; // assume the source stream gave us all that it could
+ }
+
+ if (fillBuf() == -1) {
+ break; // source is exhausted
+ }
}
- while (true) {
- int read;
- /*
- * If we're not marked and the required size is greater than the
- * buffer, simply read the bytes directly bypassing the buffer.
- */
- if (markpos == -1 && required >= buf.length) {
- read = in.read(buffer, offset, required);
- if (read == -1) {
- return required == length ? -1 : length - required;
- }
- } else {
- if (fillbuf() == -1) {
- return required == length ? -1 : length - required;
- }
- read = count - pos >= required ? required : count - pos;
- System.arraycopy(buf, pos, buffer, offset, read);
- pos += read;
- }
- required -= read;
- if (required == 0) {
- return length;
- }
- if (!in.ready()) {
- return length - required;
- }
- offset += read;
- }
+ int count = length - outstanding;
+ return (count > 0 || count == length) ? count : -1;
}
}
@@ -341,11 +386,11 @@
if (isClosed()) {
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
}
- /* Are there buffered characters available? */
- if ((pos >= count) && (fillbuf() == -1)) {
+ /* has the underlying stream been exhausted? */
+ if (pos == end && fillBuf() == -1) {
return null;
}
- for (int charPos = pos; charPos < count; charPos++) {
+ for (int charPos = pos; charPos < end; charPos++) {
char ch = buf[charPos];
// BEGIN android-note
// a switch statement may be more efficient
@@ -360,7 +405,7 @@
} else if (ch == '\r') {
String res = new String(buf, pos, charPos - pos);
pos = charPos + 1;
- if (((pos < count) || (fillbuf() != -1))
+ if (((pos < end) || (fillBuf() != -1))
&& (buf[pos] == '\n')) {
pos++;
}
@@ -372,30 +417,28 @@
StringBuilder result = new StringBuilder(80);
/* Typical Line Length */
- result.append(buf, pos, count - pos);
- pos = count;
+ result.append(buf, pos, end - pos);
while (true) {
+ pos = end;
+
/* Are there buffered characters available? */
- if (pos >= count) {
- if (eol == '\n') {
- return result.toString();
- }
- // attempt to fill buffer
- if (fillbuf() == -1) {
- // characters or null.
- return result.length() > 0 || eol != '\0' ? result
- .toString() : null;
- }
+ if (eol == '\n') {
+ return result.toString();
}
- for (int charPos = pos; charPos < count; charPos++) {
- // BEGIN android-note
- // use a local variable for buf[charPos] and a switch statement
- // END android-note
+ // attempt to fill buffer
+ if (fillBuf() == -1) {
+ // characters or null.
+ return result.length() > 0 || eol != '\0'
+ ? result.toString()
+ : null;
+ }
+ for (int charPos = pos; charPos < end; charPos++) {
+ char c = buf[charPos];
if (eol == '\0') {
- if ((buf[charPos] == '\n' || buf[charPos] == '\r')) {
- eol = buf[charPos];
+ if ((c == '\n' || c == '\r')) {
+ eol = c;
}
- } else if (eol == '\r' && (buf[charPos] == '\n')) {
+ } else if (eol == '\r' && c == '\n') {
if (charPos > pos) {
result.append(buf, pos, charPos - pos - 1);
}
@@ -410,11 +453,10 @@
}
}
if (eol == '\0') {
- result.append(buf, pos, count - pos);
+ result.append(buf, pos, end - pos);
} else {
- result.append(buf, pos, count - pos - 1);
+ result.append(buf, pos, end - pos - 1);
}
- pos = count;
}
}
@@ -437,7 +479,7 @@
if (isClosed()) {
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
}
- return ((count - pos) > 0) || in.ready();
+ return ((end - pos) > 0) || in.ready();
}
}
@@ -457,17 +499,17 @@
if (isClosed()) {
throw new IOException(Msg.getString("K005b")); //$NON-NLS-1$
}
- if (markpos == -1) {
+ if (mark == -1) {
throw new IOException(Msg.getString("K005c")); //$NON-NLS-1$
}
- pos = markpos;
+ pos = mark;
}
}
/**
* Skips {@code amount} characters in this reader. Subsequent
* {@code read()}s will not return these characters unless {@code reset()}
- * is used. Skipping characters may invalidate a mark if {@code readlimit}
+ * is used. Skipping characters may invalidate a mark if {@code markLimit}
* is surpassed.
*
* @param amount
@@ -493,24 +535,24 @@
if (amount < 1) {
return 0;
}
- if (count - pos >= amount) {
+ if (end - pos >= amount) {
pos += amount;
return amount;
}
- long read = count - pos;
- pos = count;
+ long read = end - pos;
+ pos = end;
while (read < amount) {
- if (fillbuf() == -1) {
+ if (fillBuf() == -1) {
return read;
}
- if (count - pos >= amount - read) {
+ if (end - pos >= amount - read) {
pos += amount - read;
return amount;
}
// Couldn't get all the characters, skip what we read
- read += (count - pos);
- pos = count;
+ read += (end - pos);
+ pos = end;
}
return amount;
}
diff --git a/luni/src/main/java/java/io/CharArrayReader.java b/luni/src/main/java/java/io/CharArrayReader.java
index d2757f6..6753faa 100644
--- a/luni/src/main/java/java/io/CharArrayReader.java
+++ b/luni/src/main/java/java/io/CharArrayReader.java
@@ -213,20 +213,16 @@
// BEGIN android-note
// changed array notation to be consistent with the rest of harmony
// END android-note
- // avoid int overflow
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // made implicit null check explicit,
- // removed redundant check, used (offset | len) < 0 instead of
- // (offset < 0) || (len < 0) to safe one operation
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ if (offset < 0 || offset > buffer.length) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(
+ Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- if ((offset | len) < 0 || len > buffer.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (len < 0 || len > buffer.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(
+ Msg.getString("K0031", len)); //$NON-NLS-1$
}
- // END android-changed
synchronized (lock) {
if (isClosed()) {
throw new IOException(Msg.getString("K0060")); //$NON-NLS-1$
diff --git a/luni/src/main/java/java/io/DataOutputStream.java b/luni/src/main/java/java/io/DataOutputStream.java
index 18e04a5..4152173 100644
--- a/luni/src/main/java/java/io/DataOutputStream.java
+++ b/luni/src/main/java/java/io/DataOutputStream.java
@@ -280,6 +280,19 @@
written += 8;
}
+ int writeLongToBuffer(long val,
+ byte[] buffer, int offset) throws IOException {
+ buffer[offset++] = (byte) (val >> 56);
+ buffer[offset++] = (byte) (val >> 48);
+ buffer[offset++] = (byte) (val >> 40);
+ buffer[offset++] = (byte) (val >> 32);
+ buffer[offset++] = (byte) (val >> 24);
+ buffer[offset++] = (byte) (val >> 16);
+ buffer[offset++] = (byte) (val >> 8);
+ buffer[offset++] = (byte) val;
+ return offset;
+ }
+
/**
* Writes the specified 16-bit short to the target stream. Only the lower
* two bytes of the integer {@code val} are written, with the higher one
@@ -299,6 +312,13 @@
written += 2;
}
+ int writeShortToBuffer(int val,
+ byte[] buffer, int offset) throws IOException {
+ buffer[offset++] = (byte) (val >> 8);
+ buffer[offset++] = (byte) val;
+ return offset;
+ }
+
/**
* Writes the specified encoded in {@link DataInput modified UTF-8} to this
* stream.
@@ -317,8 +337,14 @@
if (utfCount > 65535) {
throw new UTFDataFormatException(Msg.getString("K0068")); //$NON-NLS-1$
}
- writeShort((int) utfCount);
- writeUTFBytes(str, utfCount);
+ byte[] buffer = new byte[(int)utfCount + 2];
+ int offset = 0;
+ offset = writeShortToBuffer((int) utfCount, buffer, offset);
+ // BEGIN android-changed
+ // removed unused parameter count
+ offset = writeUTFBytesToBuffer(str, buffer, offset);
+ // BEGIN android-changed
+ write(buffer, 0, offset);
}
long countUTFBytes(String str) {
@@ -336,24 +362,25 @@
return utfCount;
}
- void writeUTFBytes(String str, long count) throws IOException {
- int size = (int) count;
+ int writeUTFBytesToBuffer(String str,
+ byte[] buffer, int offset) throws IOException {
+ // BEGIN android-note
+ // removed unused parameter count
+ // END android-note
int length = str.length();
- byte[] utfBytes = new byte[size];
- int utfIndex = 0;
for (int i = 0; i < length; i++) {
int charValue = str.charAt(i);
if (charValue > 0 && charValue <= 127) {
- utfBytes[utfIndex++] = (byte) charValue;
+ buffer[offset++] = (byte) charValue;
} else if (charValue <= 2047) {
- utfBytes[utfIndex++] = (byte) (0xc0 | (0x1f & (charValue >> 6)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
+ buffer[offset++] = (byte) (0xc0 | (0x1f & (charValue >> 6)));
+ buffer[offset++] = (byte) (0x80 | (0x3f & charValue));
} else {
- utfBytes[utfIndex++] = (byte) (0xe0 | (0x0f & (charValue >> 12)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & (charValue >> 6)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
+ buffer[offset++] = (byte) (0xe0 | (0x0f & (charValue >> 12)));
+ buffer[offset++] = (byte) (0x80 | (0x3f & (charValue >> 6)));
+ buffer[offset++] = (byte) (0x80 | (0x3f & charValue));
}
}
- write(utfBytes, 0, utfIndex);
+ return offset;
}
}
diff --git a/luni/src/main/java/java/io/EmulatedFieldsForDumping.java b/luni/src/main/java/java/io/EmulatedFieldsForDumping.java
index 16c7986..c3743dd 100644
--- a/luni/src/main/java/java/io/EmulatedFieldsForDumping.java
+++ b/luni/src/main/java/java/io/EmulatedFieldsForDumping.java
@@ -192,7 +192,6 @@
*/
@Override
@Deprecated
- @SuppressWarnings("deprecation")
public void write(ObjectOutput output) throws IOException {
EmulatedFields.ObjectSlot[] slots = emulatedFields.slots();
for (int i = 0; i < slots.length; i++) {
diff --git a/luni/src/main/java/java/io/File.java b/luni/src/main/java/java/io/File.java
index c802995..521623d 100644
--- a/luni/src/main/java/java/io/File.java
+++ b/luni/src/main/java/java/io/File.java
@@ -25,7 +25,6 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.harmony.luni.internal.io.FileCanonPathCache;
import org.apache.harmony.luni.util.DeleteOnExit;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
@@ -497,11 +496,15 @@
public String getCanonicalPath() throws IOException {
byte[] result = properPath(false);
String absPath = Util.toUTF8String(result);
- String canonPath = FileCanonPathCache.get(absPath);
- if (canonPath != null) {
- return canonPath;
- }
+ // BEGIN android-removed
+ // caching the canonical path is completely bogus
+ // String canonPath = FileCanonPathCache.get(absPath);
+ // if (canonPath != null) {
+ // return canonPath;
+ // }
+ // END android-removed
+
if(separatorChar == '/') {
// resolve the full path first
result = resolveLink(result, result.length, false);
@@ -573,9 +576,13 @@
newResult[newLength] = 0;
newResult = getCanonImpl(newResult);
newLength = newResult.length;
- canonPath = Util.toUTF8String(newResult, 0, newLength);
- FileCanonPathCache.put(absPath, canonPath);
- return canonPath;
+
+ // BEGIN android-changed
+ // caching the canonical path is completely bogus
+ return Util.toUTF8String(newResult, 0, newLength);
+ // FileCanonPathCache.put(absPath, canonPath);
+ // return canonPath;
+ // END android-changed
}
/*
@@ -761,9 +768,8 @@
* Indicates if this file's pathname is absolute. Whether a pathname is
* absolute is platform specific. On UNIX, absolute paths must start with
* the character '/'; on Windows it is absolute if either it starts with
- * '\', '/', '\\' (to represent a file server), or a letter followed by a
- * colon.
- *
+ * '\\' (to represent a file server), or a letter followed by a colon.
+ *
* @return {@code true} if this file's pathname is absolute, {@code false}
* otherwise.
* @see #getPath
@@ -775,10 +781,6 @@
// END android-changed
}
- // BEGIN android-removed
- // private native boolean isAbsoluteImpl(byte[] filePath);
- // END android-removed
-
/**
* Indicates if this file represents a <em>directory</em> on the
* underlying file system.
@@ -1358,8 +1360,10 @@
if (properPath != null) {
return properPath;
}
- if(path.length() > 0 && path.charAt(0) == separatorChar) {
- return properPath = Util.getBytes(path);
+
+ if (isAbsolute()) {
+ byte[] pathBytes = Util.getUTF8Bytes(path);
+ return properPath = pathBytes;
}
// Check security by getting user.dir when the path is not absolute
String userdir;
@@ -1380,10 +1384,6 @@
}
// END android-changed
- // BEGIN android-removed
- // private static native byte[] properPathImpl(byte[] path);
- // END android-removed
-
/**
* Renames this file to the name represented by the {@code dest} file. This
* works for both normal files and directories.
diff --git a/luni/src/main/java/java/io/FileInputStream.java b/luni/src/main/java/java/io/FileInputStream.java
index 1243262..077cd23 100644
--- a/luni/src/main/java/java/io/FileInputStream.java
+++ b/luni/src/main/java/java/io/FileInputStream.java
@@ -69,9 +69,14 @@
super();
SecurityManager security = System.getSecurityManager();
if (security != null) {
+ // For compatibility, nulls are passed to the manager.
String filePath = (null == file ? null : file.getPath());
security.checkRead(filePath);
}
+ if (file == null) {
+ // KA001=Argument must not be null
+ throw new NullPointerException(Msg.getString("KA001")); //$NON-NLS-1$
+ }
fd = new FileDescriptor();
fd.readOnly = true;
fd.descriptor = fileSystem.open(file.properPath(true),
@@ -312,25 +317,24 @@
}
openCheck();
synchronized (repositioningLock) {
- // stdin requires special handling
- if (fd == FileDescriptor.in) {
- return (int) fileSystem.ttyRead(buffer, offset, count);
- }
+ // BEGIN android-changed
+ // If you only support Linux, there's nothing special about stdin.
return (int) fileSystem.read(fd.descriptor, buffer, offset, count);
+ // END android-changed
}
}
/**
* Skips {@code count} number of bytes in this stream. Subsequent
- * {@code read()}'s will not return these bytes unless {@code reset()} is
- * used. This method may perform multiple reads to read {@code count} bytes.
+ * {@code read()}s will not return these bytes unless {@code reset()} is
+ * used. If the underlying stream is unseekable, an IOException is thrown.
*
* @param count
* the number of bytes to skip.
* @return the number of bytes actually skipped.
* @throws IOException
- * if {@code count < 0}, this stream is closed or another
- * IOException occurs.
+ * if {@code count < 0}, this stream is closed or unseekable,
+ * or another IOException occurs.
*/
@Override
public long skip(long count) throws IOException {
@@ -344,29 +348,18 @@
throw new IOException(Msg.getString("KA013")); //$NON-NLS-1$
}
- // stdin requires special handling
- if (fd == FileDescriptor.in) {
- // Read and discard count bytes in 8k chunks
- long skipped = 0, numRead;
- int chunk = count < 8192 ? (int) count : 8192;
- byte[] buffer = new byte[chunk];
- for (long i = count / chunk; i >= 0; i--) {
- numRead = fileSystem.ttyRead(buffer, 0, chunk);
- skipped += numRead;
- if (numRead < chunk) {
- return skipped;
- }
- }
- return skipped;
- }
-
+ // BEGIN android-changed
+ // The RI doesn't treat stdin as special. It throws IOException for
+ // all non-seekable streams, so we do too. If you did want to support
+ // non-seekable streams, the best way to do it would be to recognize
+ // when lseek(2) fails with ESPIPE and call super.skip(count).
synchronized (repositioningLock) {
- final long currentPosition = fileSystem.seek(fd.descriptor, 0L,
- IFileSystem.SEEK_CUR);
- final long newPosition = fileSystem.seek(fd.descriptor,
- currentPosition + count, IFileSystem.SEEK_SET);
- return newPosition - currentPosition;
+ // Our seek returns the new offset, but we know it will throw an
+ // exception if it couldn't perform exactly the seek we asked for.
+ fileSystem.seek(fd.descriptor, count, IFileSystem.SEEK_CUR);
+ return count;
}
+ // END android-changed
}
private synchronized void openCheck() throws IOException {
diff --git a/luni/src/main/java/java/io/FilterOutputStream.java b/luni/src/main/java/java/io/FilterOutputStream.java
index 66765f9..fa837ee 100644
--- a/luni/src/main/java/java/io/FilterOutputStream.java
+++ b/luni/src/main/java/java/io/FilterOutputStream.java
@@ -102,7 +102,7 @@
* the buffer to write.
* @param offset
* the index of the first byte in {@code buffer} to write.
- * @param count
+ * @param length
* the number of bytes in {@code buffer} to write.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if
@@ -112,25 +112,20 @@
* if an I/O error occurs while writing to this stream.
*/
@Override
- public void write(byte[] buffer, int offset, int count) throws IOException {
+ public void write(byte[] buffer, int offset, int length) throws IOException {
// BEGIN android-note
// changed array notation to be consistent with the rest of harmony
// END android-note
- // avoid int overflow, force null buffer check first
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, made implicit null check explicit,
- // used (offset | count) < 0 instead of (offset < 0) || (count < 0)
- // to safe one operation
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ // Force null buffer check first!
+ if (offset > buffer.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- if ((offset | count) < 0 || count > buffer.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (length < 0 || length > buffer.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- // END android-changed
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < length; i++) {
// Call write() instead of out.write() since subclasses could
// override the write() method.
write(buffer[offset + i]);
diff --git a/luni/src/main/java/java/io/InputStream.java b/luni/src/main/java/java/io/InputStream.java
index f20ce7d..33a5cfd 100644
--- a/luni/src/main/java/java/io/InputStream.java
+++ b/luni/src/main/java/java/io/InputStream.java
@@ -17,9 +17,7 @@
package java.io;
-// BEGIN android-added
import org.apache.harmony.luni.util.Msg;
-// END android-added
/**
* The base class for all input streams. An input stream is a means of reading
@@ -157,20 +155,15 @@
// BEGIN android-note
// changed array notation to be consistent with the rest of harmony
// END android-note
- // avoid int overflow, check null b
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, made implicit null check explicit,
- // used (offset | length) < 0 instead of (offset < 0) || (length < 0)
- // to safe one operation
- if (b == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ // Force null check for b first!
+ if (offset > b.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
+ }
+ if (length < 0 || length > b.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- if ((offset | length) < 0 || length > b.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
- }
- // END android-changed
for (int i = 0; i < length; i++) {
int c;
try {
@@ -224,11 +217,16 @@
}
long skipped = 0;
int toRead = n < 4096 ? (int) n : 4096;
- if (skipBuf == null || skipBuf.length < toRead) {
- skipBuf = new byte[toRead];
+ // We are unsynchronized, so take a local copy of the skipBuf at some
+ // point in time.
+ byte[] localBuf = skipBuf;
+ if (localBuf == null || localBuf.length < toRead) {
+ // May be lazily written back to the static. No matter if it
+ // overwrites somebody else's store.
+ skipBuf = localBuf = new byte[toRead];
}
while (skipped < n) {
- int read = read(skipBuf, 0, toRead);
+ int read = read(localBuf, 0, toRead);
if (read == -1) {
return skipped;
}
diff --git a/luni/src/main/java/java/io/LineNumberInputStream.java b/luni/src/main/java/java/io/LineNumberInputStream.java
index 1a40177..3df3a05 100644
--- a/luni/src/main/java/java/io/LineNumberInputStream.java
+++ b/luni/src/main/java/java/io/LineNumberInputStream.java
@@ -17,9 +17,7 @@
package java.io;
-// BEGIN android-added
import org.apache.harmony.luni.util.Msg;
-// END android-added
/**
* Wraps an existing {@link InputStream} and counts the line terminators
@@ -171,19 +169,15 @@
*/
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
- // BEGIN android-changed
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ // Force buffer null check first!
+ if (offset > buffer.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
+ }
+ if (length < 0 || length > buffer.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- // avoid int overflow
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, used (offset | length) < 0
- // instead of (offset < 0) || (length < 0) to safe one operation
- if ((offset | length) < 0 || length > buffer.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
- }
- // END android-changed
for (int i = 0; i < length; i++) {
int currentChar;
diff --git a/luni/src/main/java/java/io/NotSerializableException.java b/luni/src/main/java/java/io/NotSerializableException.java
index f6e93a7..d85586a 100644
--- a/luni/src/main/java/java/io/NotSerializableException.java
+++ b/luni/src/main/java/java/io/NotSerializableException.java
@@ -19,9 +19,9 @@
/**
* Signals that an object that is not serializable has been passed into the
- * {@code ObjectOutput.writeObject()} mthod. This can happen if the object does
- * not implement {@code Serializable} or {@code Externalizable}, or if it is
- * serializable but it overrides {@code writeObject(ObjectOutputStream)} and
+ * {@code ObjectOutput.writeObject()} method. This can happen if the object
+ * does not implement {@code Serializable} or {@code Externalizable}, or if it
+ * is serializable but it overrides {@code writeObject(ObjectOutputStream)} and
* explicitly prevents serialization by throwing this type of exception.
*
* @see ObjectOutput#writeObject(Object)
diff --git a/luni/src/main/java/java/io/ObjectInputStream.java b/luni/src/main/java/java/io/ObjectInputStream.java
index 6d24eb2..df6d9a2 100644
--- a/luni/src/main/java/java/io/ObjectInputStream.java
+++ b/luni/src/main/java/java/io/ObjectInputStream.java
@@ -701,19 +701,15 @@
*/
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
- // BEGIN android-changed
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ // Force buffer null check first!
+ if (offset > buffer.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // avoid int overflow
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, used (offset | length) < 0 instead of
- // (offset < 0) || (length < 0) to safe one operation
- if ((offset | length) < 0 || length > buffer.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (length < 0 || length > buffer.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- // END android-changed
if (length == 0) {
return 0;
}
diff --git a/luni/src/main/java/java/io/ObjectOutputStream.java b/luni/src/main/java/java/io/ObjectOutputStream.java
index e3c1471..7c85d4b 100644
--- a/luni/src/main/java/java/io/ObjectOutputStream.java
+++ b/luni/src/main/java/java/io/ObjectOutputStream.java
@@ -1617,14 +1617,19 @@
private Integer writeNewString(String object, boolean unshared)
throws IOException {
long count = output.countUTFBytes(object);
+ byte[] buffer;
+ int offset = 0;
if (count <= 0xffff) {
- output.writeByte(TC_STRING);
- output.writeShort((short) count);
+ buffer = new byte[(int)count+3];
+ buffer[offset++] = TC_STRING;
+ offset = output.writeShortToBuffer((short) count, buffer, offset);
} else {
- output.writeByte(TC_LONGSTRING);
- output.writeLong(count);
+ buffer = new byte[(int)count+9];
+ buffer[offset++] = TC_LONGSTRING;
+ offset = output.writeLongToBuffer(count, buffer, offset);
}
- output.writeUTFBytes(object, count);
+ offset = output.writeUTFBytesToBuffer(object, buffer, offset);
+ output.write(buffer, 0, offset);
Integer handle = nextHandle();
diff --git a/luni/src/main/java/java/io/PipedInputStream.java b/luni/src/main/java/java/io/PipedInputStream.java
index a6b0336..6d1c007 100644
--- a/luni/src/main/java/java/io/PipedInputStream.java
+++ b/luni/src/main/java/java/io/PipedInputStream.java
@@ -15,6 +15,13 @@
* limitations under the License.
*/
+// BEGIN android-note
+// We've made several changes including:
+// - delayed buffer creation until pipe connection
+// - throw an IOException when a pipe is closed during a write
+// - improved consistency with PipedReader
+// END android-note
+
package java.io;
import org.apache.harmony.luni.util.Msg;
@@ -28,9 +35,11 @@
*/
public class PipedInputStream extends InputStream {
- private Thread lastReader, lastWriter;
+ private Thread lastReader;
- private boolean isClosed = false;
+ private Thread lastWriter;
+
+ private boolean isClosed;
/**
* The circular buffer through which data is passed. Data is read from the
@@ -60,7 +69,7 @@
/**
* The index in {@code buffer} where the next byte will be read.
*/
- protected int out = 0;
+ protected int out;
/**
* The size of the default pipe in bytes.
@@ -70,16 +79,14 @@
/**
* Indicates if this pipe is connected.
*/
- boolean isConnected = false;
+ boolean isConnected;
/**
* Constructs a new unconnected {@code PipedInputStream}. The resulting
* stream must be connected to a {@link PipedOutputStream} before data may
* be read from it.
*/
- public PipedInputStream() {
- /* empty */
- }
+ public PipedInputStream() {}
/**
* Constructs a new {@code PipedInputStream} connected to the
@@ -120,14 +127,9 @@
* if an error occurs while closing this stream.
*/
@Override
- public void close() throws IOException {
- synchronized (this) {
- /* No exception thrown if already closed */
- if (buffer != null) {
- /* Release buffer to indicate closed. */
- buffer = null;
- }
- }
+ public synchronized void close() throws IOException {
+ buffer = null;
+ notifyAll();
}
/**
@@ -145,6 +147,20 @@
}
/**
+ * Establishes the connection to the PipedOutputStream.
+ *
+ * @throws IOException
+ * If this Reader is already connected.
+ */
+ synchronized void establishConnection() throws IOException {
+ if (isConnected) {
+ throw new IOException(Msg.getString("K007a")); //$NON-NLS-1$
+ }
+ buffer = new byte[PipedInputStream.PIPE_SIZE];
+ isConnected = true;
+ }
+
+ /**
* Reads a single byte from this stream and returns it as an integer in the
* range from 0 to 255. Returns -1 if the end of this stream has been
* reached. If there is no data in the pipe, this method blocks until data
@@ -408,20 +424,21 @@
} catch (InterruptedException e) {
throw new InterruptedIOException();
}
- if (buffer != null) {
- if (in == -1) {
- in = 0;
- }
- buffer[in++] = (byte) oneByte;
- if (in == buffer.length) {
- in = 0;
- }
-
- // BEGIN android-added
- // let blocked readers read the newly available data
- notifyAll();
- // END android-added
+ if (buffer == null) {
+ throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
}
+ if (in == -1) {
+ in = 0;
+ }
+ buffer[in++] = (byte) oneByte;
+ if (in == buffer.length) {
+ in = 0;
+ }
+
+ // BEGIN android-added
+ // let blocked readers read the newly available data
+ notifyAll();
+ // END android-added
}
synchronized void done() {
diff --git a/luni/src/main/java/java/io/PipedOutputStream.java b/luni/src/main/java/java/io/PipedOutputStream.java
index 15ee930..4b640d4 100644
--- a/luni/src/main/java/java/io/PipedOutputStream.java
+++ b/luni/src/main/java/java/io/PipedOutputStream.java
@@ -15,6 +15,12 @@
* limitations under the License.
*/
+// BEGIN android-note
+// We've made several changes including:
+// - avoid shallow concurrency problems
+// - improved consistency with PipedWriter
+// END android-note
+
package java.io;
import org.apache.harmony.luni.util.Msg;
@@ -67,8 +73,9 @@
@Override
public void close() throws IOException {
// Is the pipe connected?
- if (dest != null) {
- dest.done();
+ PipedInputStream stream = dest;
+ if (stream != null) {
+ stream.done();
dest = null;
}
}
@@ -83,18 +90,17 @@
* if either stream is already connected.
*/
public void connect(PipedInputStream stream) throws IOException {
- if (null == stream) {
+ if (stream == null) {
throw new NullPointerException();
}
- if (this.dest != null) {
- throw new IOException(Msg.getString("K0079")); //$NON-NLS-1$
- }
synchronized (stream) {
+ if (this.dest != null) {
+ throw new IOException(Msg.getString("K0079")); //$NON-NLS-1$
+ }
if (stream.isConnected) {
throw new IOException(Msg.getString("K007a")); //$NON-NLS-1$
}
- stream.buffer = new byte[PipedInputStream.PIPE_SIZE];
- stream.isConnected = true;
+ stream.establishConnection();
this.dest = stream;
}
}
@@ -108,10 +114,13 @@
*/
@Override
public void flush() throws IOException {
- if (dest != null) {
- synchronized (dest) {
- dest.notifyAll();
- }
+ PipedInputStream stream = dest;
+ if (stream == null) {
+ return;
+ }
+
+ synchronized (stream) {
+ stream.notifyAll();
}
}
@@ -145,13 +154,6 @@
*/
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
- // BEGIN android-note
- // changed array notation to be consistent with the rest of harmony
- // END android-note
- if (dest == null) {
- // K007b=Pipe Not Connected
- throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
- }
super.write(buffer, offset, count);
}
@@ -177,9 +179,11 @@
*/
@Override
public void write(int oneByte) throws IOException {
- if (dest == null) {
+ PipedInputStream stream = dest;
+ if (stream == null) {
+ // K007b=Pipe Not Connected
throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
}
- dest.receive(oneByte);
+ stream.receive(oneByte);
}
}
diff --git a/luni/src/main/java/java/io/PipedReader.java b/luni/src/main/java/java/io/PipedReader.java
index 251ac90..d137a0d 100644
--- a/luni/src/main/java/java/io/PipedReader.java
+++ b/luni/src/main/java/java/io/PipedReader.java
@@ -17,6 +17,13 @@
package java.io;
+// BEGIN android-note
+// We've made several changes including:
+// - throw an IOException when a pipe is closed during a write
+// - fix shallow concurrency problems, always lock on 'this'
+// - improved consistency with PipedInputStream
+// END android-note
+
import org.apache.harmony.luni.util.Msg;
/**
@@ -35,13 +42,27 @@
private boolean isClosed;
/**
- * The circular buffer through which data is passed.
+ * The circular buffer through which data is passed. Data is read from the
+ * range {@code [out, in)} and written to the range {@code [in, out)}.
+ * Data in the buffer is either sequential: <pre>
+ * { - - - X X X X X X X - - - - - }
+ * ^ ^
+ * | |
+ * out in</pre>
+ * ...or wrapped around the buffer's end: <pre>
+ * { X X X X - - - - - - - - X X X }
+ * ^ ^
+ * | |
+ * in out</pre>
+ * When the buffer is empty, {@code in == -1}. Reading when the buffer is
+ * empty will block until data is available. When the buffer is full,
+ * {@code in == out}. Writing when the buffer is full will block until free
+ * space is available.
*/
- private char data[];
+ private char[] buffer;
/**
- * The index in {@code buffer} where the next character will be
- * written.
+ * The index in {@code buffer} where the next character will be written.
*/
private int in = -1;
@@ -58,18 +79,14 @@
/**
* Indicates if this pipe is connected
*/
- private boolean isConnected;
+ boolean isConnected;
/**
* Constructs a new unconnected {@code PipedReader}. The resulting reader
* must be connected to a {@code PipedWriter} before data may be read from
* it.
- *
- * @see PipedWriter
*/
- public PipedReader() {
- data = new char[PIPE_SIZE];
- }
+ public PipedReader() {}
/**
* Constructs a new {@code PipedReader} connected to the {@link PipedWriter}
@@ -82,7 +99,6 @@
* if {@code out} is already connected.
*/
public PipedReader(PipedWriter out) throws IOException {
- this();
connect(out);
}
@@ -94,14 +110,9 @@
* if an error occurs while closing this reader.
*/
@Override
- public void close() throws IOException {
- synchronized (lock) {
- /* No exception thrown if already closed */
- if (data != null) {
- /* Release buffer to indicate closed. */
- data = null;
- }
- }
+ public synchronized void close() throws IOException {
+ buffer = null;
+ notifyAll();
}
/**
@@ -115,9 +126,7 @@
* src} is already connected.
*/
public void connect(PipedWriter src) throws IOException {
- synchronized (lock) {
- src.connect(this);
- }
+ src.connect(this);
}
/**
@@ -126,16 +135,12 @@
* @throws IOException
* If this Reader is already connected.
*/
- void establishConnection() throws IOException {
- synchronized (lock) {
- if (data == null) {
- throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
- }
- if (isConnected) {
- throw new IOException(Msg.getString("K007a")); //$NON-NLS-1$
- }
- isConnected = true;
+ synchronized void establishConnection() throws IOException {
+ if (isConnected) {
+ throw new IOException(Msg.getString("K007a")); //$NON-NLS-1$
}
+ buffer = new char[PIPE_SIZE];
+ isConnected = true;
}
/**
@@ -192,95 +197,93 @@
* alive.
*/
@Override
- public int read(char[] buffer, int offset, int count) throws IOException {
- synchronized (lock) {
- if (!isConnected) {
- throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
- }
- if (data == null) {
- throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
- }
- // avoid int overflow
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // made implicit null check explicit,
- // used (offset | count) < 0 instead of (offset < 0) || (count < 0)
- // to safe one operation
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
- }
- if ((offset | count) < 0 || count > buffer.length - offset) {
- throw new IndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
- }
- // END android-changed
- if (count == 0) {
- return 0;
- }
- /**
- * Set the last thread to be reading on this PipedReader. If
- * lastReader dies while someone is waiting to write an IOException
- * of "Pipe broken" will be thrown in receive()
- */
- lastReader = Thread.currentThread();
- try {
- boolean first = true;
- while (in == -1) {
- // Are we at end of stream?
- if (isClosed) {
- return -1;
- }
- if (!first && lastWriter != null && !lastWriter.isAlive()) {
- throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
- }
- first = false;
- // Notify callers of receive()
- lock.notifyAll();
- lock.wait(1000);
+ public synchronized int read(char[] buffer, int offset, int count) throws IOException {
+ if (!isConnected) {
+ throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
+ }
+ if (this.buffer == null) {
+ throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
+ }
+ // avoid int overflow
+ // BEGIN android-changed
+ // Exception priorities (in case of multiple errors) differ from
+ // RI, but are spec-compliant.
+ // made implicit null check explicit,
+ // used (offset | count) < 0 instead of (offset < 0) || (count < 0)
+ // to safe one operation
+ if (buffer == null) {
+ throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ }
+ if ((offset | count) < 0 || count > buffer.length - offset) {
+ throw new IndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ }
+ // END android-changed
+ if (count == 0) {
+ return 0;
+ }
+ /**
+ * Set the last thread to be reading on this PipedReader. If
+ * lastReader dies while someone is waiting to write an IOException
+ * of "Pipe broken" will be thrown in receive()
+ */
+ lastReader = Thread.currentThread();
+ try {
+ boolean first = true;
+ while (in == -1) {
+ // Are we at end of stream?
+ if (isClosed) {
+ return -1;
}
- } catch (InterruptedException e) {
- throw new InterruptedIOException();
- }
-
- int copyLength = 0;
- /* Copy chars from out to end of buffer first */
- if (out >= in) {
- copyLength = count > data.length - out ? data.length - out
- : count;
- System.arraycopy(data, out, buffer, offset, copyLength);
- out += copyLength;
- if (out == data.length) {
- out = 0;
+ if (!first && lastWriter != null && !lastWriter.isAlive()) {
+ throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
}
- if (out == in) {
- // empty buffer
- in = -1;
- out = 0;
- }
+ first = false;
+ // Notify callers of receive()
+ notifyAll();
+ wait(1000);
}
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException();
+ }
- /*
- * Did the read fully succeed in the previous copy or is the buffer
- * empty?
- */
- if (copyLength == count || in == -1) {
- return copyLength;
- }
-
- int charsCopied = copyLength;
- /* Copy bytes from 0 to the number of available bytes */
- copyLength = in - out > count - copyLength ? count - copyLength
- : in - out;
- System.arraycopy(data, out, buffer, offset + charsCopied,
- copyLength);
+ int copyLength = 0;
+ /* Copy chars from out to end of buffer first */
+ if (out >= in) {
+ copyLength = count > this.buffer.length - out ? this.buffer.length - out
+ : count;
+ System.arraycopy(this.buffer, out, buffer, offset, copyLength);
out += copyLength;
+ if (out == this.buffer.length) {
+ out = 0;
+ }
if (out == in) {
// empty buffer
in = -1;
out = 0;
}
- return charsCopied + copyLength;
}
+
+ /*
+ * Did the read fully succeed in the previous copy or is the buffer
+ * empty?
+ */
+ if (copyLength == count || in == -1) {
+ return copyLength;
+ }
+
+ int charsCopied = copyLength;
+ /* Copy bytes from 0 to the number of available bytes */
+ copyLength = in - out > count - copyLength ? count - copyLength
+ : in - out;
+ System.arraycopy(this.buffer, out, buffer, offset + charsCopied,
+ copyLength);
+ out += copyLength;
+ if (out == in) {
+ // empty buffer
+ in = -1;
+ out = 0;
+ }
+ return charsCopied + copyLength;
}
/**
@@ -298,16 +301,14 @@
* @see #read(char[], int, int)
*/
@Override
- public boolean ready() throws IOException {
- synchronized (lock) {
- if (!isConnected) {
- throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
- }
- if (data == null) {
- throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
- }
- return in != -1;
+ public synchronized boolean ready() throws IOException {
+ if (!isConnected) {
+ throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
}
+ if (buffer == null) {
+ throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
+ }
+ return in != -1;
}
/**
@@ -324,43 +325,41 @@
* If the stream is already closed or another IOException
* occurs.
*/
- void receive(char oneChar) throws IOException {
- synchronized (lock) {
- if (data == null) {
- throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
- }
- if (lastReader != null && !lastReader.isAlive()) {
- throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
- }
- /*
- * Set the last thread to be writing on this PipedWriter. If
- * lastWriter dies while someone is waiting to read an IOException
- * of "Pipe broken" will be thrown in read()
- */
- lastWriter = Thread.currentThread();
- try {
- while (data != null && out == in) {
- lock.notifyAll();
- // BEGIN android-changed
- lock.wait(1000);
- // END android-changed
- if (lastReader != null && !lastReader.isAlive()) {
- throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
- }
+ synchronized void receive(char oneChar) throws IOException {
+ if (buffer == null) {
+ throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
+ }
+ if (lastReader != null && !lastReader.isAlive()) {
+ throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
+ }
+ /*
+ * Set the last thread to be writing on this PipedWriter. If
+ * lastWriter dies while someone is waiting to read an IOException
+ * of "Pipe broken" will be thrown in read()
+ */
+ lastWriter = Thread.currentThread();
+ try {
+ while (buffer != null && out == in) {
+ notifyAll();
+ // BEGIN android-changed
+ wait(1000);
+ // END android-changed
+ if (lastReader != null && !lastReader.isAlive()) {
+ throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
}
- } catch (InterruptedException e) {
- throw new InterruptedIOException();
}
- if (data != null) {
- if (in == -1) {
- in = 0;
- }
- data[in++] = oneChar;
- if (in == data.length) {
- in = 0;
- }
- return;
- }
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException();
+ }
+ if (buffer == null) {
+ throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
+ }
+ if (in == -1) {
+ in = 0;
+ }
+ buffer[in++] = oneChar;
+ if (in == buffer.length) {
+ in = 0;
}
}
@@ -382,80 +381,73 @@
* If the stream is already closed or another IOException
* occurs.
*/
- void receive(char[] chars, int offset, int count) throws IOException {
- synchronized (lock) {
- if (data == null) {
+ synchronized void receive(char[] chars, int offset, int count) throws IOException {
+ if (chars == null) {
+ throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ }
+ if ((offset | count) < 0 || count > chars.length - offset) {
+ throw new IndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ }
+ if (buffer == null) {
+ throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
+ }
+ if (lastReader != null && !lastReader.isAlive()) {
+ throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
+ }
+ /**
+ * Set the last thread to be writing on this PipedWriter. If
+ * lastWriter dies while someone is waiting to read an IOException
+ * of "Pipe broken" will be thrown in read()
+ */
+ lastWriter = Thread.currentThread();
+ while (count > 0) {
+ try {
+ while (buffer != null && out == in) {
+ notifyAll();
+ // BEGIN android-changed
+ wait(1000);
+ // END android-changed
+ if (lastReader != null && !lastReader.isAlive()) {
+ throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
+ }
+ }
+ } catch (InterruptedException e) {
+ throw new InterruptedIOException();
+ }
+ if (buffer == null) {
throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
}
- if (lastReader != null && !lastReader.isAlive()) {
- throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
+ if (in == -1) {
+ in = 0;
}
- /**
- * Set the last thread to be writing on this PipedWriter. If
- * lastWriter dies while someone is waiting to read an IOException
- * of "Pipe broken" will be thrown in read()
- */
- lastWriter = Thread.currentThread();
- while (count > 0) {
- try {
- while (data != null && out == in) {
- lock.notifyAll();
- // BEGIN android-changed
- lock.wait(1000);
- // END android-changed
- if (lastReader != null && !lastReader.isAlive()) {
- throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
- }
- }
- } catch (InterruptedException e) {
- throw new InterruptedIOException();
+ if (in >= out) {
+ int length = buffer.length - in;
+ if (count < length) {
+ length = count;
}
- if (data == null) {
- break;
- }
- if (in == -1) {
+ System.arraycopy(chars, offset, buffer, in, length);
+ offset += length;
+ count -= length;
+ in += length;
+ if (in == buffer.length) {
in = 0;
}
- if (in >= out) {
- int length = data.length - in;
- if (count < length) {
- length = count;
- }
- System.arraycopy(chars, offset, data, in, length);
- offset += length;
- count -= length;
- in += length;
- if (in == data.length) {
- in = 0;
- }
- }
- if (count > 0 && in != out) {
- int length = out - in;
- if (count < length) {
- length = count;
- }
- System.arraycopy(chars, offset, data, in, length);
- offset += length;
- count -= length;
- in += length;
- }
}
- if (count == 0) {
- return;
+ if (count > 0 && in != out) {
+ int length = out - in;
+ if (count < length) {
+ length = count;
+ }
+ System.arraycopy(chars, offset, buffer, in, length);
+ offset += length;
+ count -= length;
+ in += length;
}
}
}
- void done() {
- synchronized (lock) {
- isClosed = true;
- lock.notifyAll();
- }
- }
-
- void flush() {
- synchronized (lock) {
- lock.notifyAll();
- }
+ synchronized void done() {
+ isClosed = true;
+ notifyAll();
}
}
diff --git a/luni/src/main/java/java/io/PipedWriter.java b/luni/src/main/java/java/io/PipedWriter.java
index 5fc968d..b0bfa98 100644
--- a/luni/src/main/java/java/io/PipedWriter.java
+++ b/luni/src/main/java/java/io/PipedWriter.java
@@ -15,6 +15,14 @@
* limitations under the License.
*/
+// BEGIN android-note
+// We've made several changes including:
+// - move checks into the synchronized method in PipedReader
+// - reply on PipedReader's isClosed field (rather than having 2 flags)
+// - avoid shallow concurrency problems
+// - improved consistency with PipedOutputStream
+// END android-note
+
package java.io;
import org.apache.harmony.luni.util.Msg;
@@ -32,8 +40,6 @@
*/
private PipedReader dest;
- private boolean closed;
-
/**
* Constructs a new unconnected {@code PipedWriter}. The resulting writer
* must be connected to a {@code PipedReader} before data may be written to
@@ -70,13 +76,10 @@
*/
@Override
public void close() throws IOException {
- synchronized (lock) {
- /* Is the pipe connected? */
- if (dest != null) {
- dest.done();
- dest = null;
- }
- closed = true;
+ PipedReader reader = dest;
+ if (reader != null) {
+ reader.done();
+ dest = null;
}
}
@@ -84,22 +87,26 @@
* Connects this {@code PipedWriter} to a {@link PipedReader}. Any data
* written to this writer becomes readable in the reader.
*
- * @param stream
+ * @param reader
* the reader to connect to.
* @throws IOException
* if this writer is closed or already connected, or if {@code
- * stream} is already connected.
+ * reader} is already connected.
*/
- public void connect(PipedReader stream) throws IOException {
- synchronized (lock) {
+ public void connect(PipedReader reader) throws IOException {
+ if (reader == null) {
+ throw new NullPointerException();
+ }
+ synchronized (reader) {
if (this.dest != null) {
throw new IOException(Msg.getString("K0079")); //$NON-NLS-1$
}
- if (closed) {
+ if (reader.isConnected) {
throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
}
- stream.establishConnection();
- this.dest = stream;
+ reader.establishConnection();
+ this.lock = reader;
+ this.dest = reader;
}
}
@@ -112,8 +119,13 @@
*/
@Override
public void flush() throws IOException {
- if (dest != null) {
- dest.flush();
+ PipedReader reader = dest;
+ if (reader == null) {
+ return;
+ }
+
+ synchronized (reader) {
+ reader.notifyAll();
}
}
@@ -150,32 +162,12 @@
*/
@Override
public void write(char[] buffer, int offset, int count) throws IOException {
- // BEGIN android-note
- // changed array notation to be consistent with the rest of harmony
- // END android-note
- synchronized (lock) {
- if (closed) {
- throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
- }
- if (dest == null) {
- throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
- }
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
- }
-
- // avoid int overflow
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, used (offset | count) < 0
- // instead of (offset < 0) || (count < 0) to safe one operation
- if ((offset | count) < 0 || count > buffer.length - offset) {
- throw new IndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
- }
- // END android-changed
- dest.receive(buffer, offset, count);
+ PipedReader reader = dest;
+ if (reader == null) {
+ // K007b=Pipe Not Connected
+ throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
}
+ reader.receive(buffer, offset, count);
}
/**
@@ -200,14 +192,11 @@
*/
@Override
public void write(int c) throws IOException {
- synchronized (lock) {
- if (closed) {
- throw new IOException(Msg.getString("K0078")); //$NON-NLS-1$
- }
- if (dest == null) {
- throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
- }
- dest.receive((char) c);
+ PipedReader reader = dest;
+ if (reader == null) {
+ // K007b=Pipe Not Connected
+ throw new IOException(Msg.getString("K007b")); //$NON-NLS-1$
}
+ reader.receive((char) c);
}
}
diff --git a/luni/src/main/java/java/io/PrintStream.java b/luni/src/main/java/java/io/PrintStream.java
index 29d460e..8b6464b 100644
--- a/luni/src/main/java/java/io/PrintStream.java
+++ b/luni/src/main/java/java/io/PrintStream.java
@@ -658,7 +658,7 @@
* the buffer to be written.
* @param offset
* the index of the first byte in {@code buffer} to write.
- * @param count
+ * @param length
* the number of bytes in {@code buffer} to write.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
@@ -666,27 +666,23 @@
* @see #flush()
*/
@Override
- public void write(byte[] buffer, int offset, int count) {
- // BEGIN android-changed
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ public void write(byte[] buffer, int offset, int length) {
+ // Force buffer null check first!
+ if (offset > buffer.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // avoid int overflow
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, used (offset | count) < 0
- // instead of (offset < 0) || (count < 0) to safe one operation
- if ((offset | count) < 0 || count > buffer.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (length < 0 || length > buffer.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- // END android-changed
synchronized (this) {
if (out == null) {
setError();
return;
}
try {
- out.write(buffer, offset, count);
+ out.write(buffer, offset, length);
if (autoflush) {
flush();
}
diff --git a/luni/src/main/java/java/io/PushbackInputStream.java b/luni/src/main/java/java/io/PushbackInputStream.java
index 4600fa2..932a896 100644
--- a/luni/src/main/java/java/io/PushbackInputStream.java
+++ b/luni/src/main/java/java/io/PushbackInputStream.java
@@ -177,21 +177,18 @@
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
if (buf == null) {
- throw new IOException();
+ // K0059=Stream is closed
+ throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
- // BEGIN android-changed
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ // Force buffer null check first!
+ if (offset > buffer.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // avoid int overflow
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, used (offset | length) < 0
- // instead of (offset < 0) || (length < 0) to safe one operation
- if ((offset | length) < 0 || length > buffer.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (length < 0 || length > buffer.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- // END android-changed
int copiedBytes = 0, copyLength = 0, newOffset = offset;
// Are there pushback bytes available?
@@ -296,27 +293,22 @@
public void unread(byte[] buffer, int offset, int length)
throws IOException {
if (length > pos) {
- // Pushback buffer full
+ // K007e=Pushback buffer full
throw new IOException(Msg.getString("K007e")); //$NON-NLS-1$
}
- // avoid int overflow
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, made implicit null check explicit
- // used (offset | length) < 0 instead of (offset < 0) || (length < 0)
- // to safe one operation
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ if (offset > buffer.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- if ((offset | length) < 0 || length > buffer.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (length < 0 || length > buffer.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- // END android-changed
-
if (buf == null) {
- throw new IOException();
+ // K0059=Stream is closed
+ throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
+
System.arraycopy(buffer, offset, buf, pos - length, length);
pos = pos - length;
}
diff --git a/luni/src/main/java/java/io/PushbackReader.java b/luni/src/main/java/java/io/PushbackReader.java
index 606ecb4..016cd2f 100644
--- a/luni/src/main/java/java/io/PushbackReader.java
+++ b/luni/src/main/java/java/io/PushbackReader.java
@@ -298,7 +298,7 @@
* reader.
* @param offset
* the index of the first byte in {@code buffer} to push back.
- * @param count
+ * @param length
* the number of bytes to push back.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if
@@ -311,29 +311,27 @@
* @throws NullPointerException
* if {@code buffer} is {@code null}.
*/
- public void unread(char[] buffer, int offset, int count) throws IOException {
+ public void unread(char[] buffer, int offset, int length) throws IOException {
synchronized (lock) {
if (buf == null) {
+ // K0059=Stream is closed
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
- if (count > pos) {
- // Pushback buffer full
+ if (length > pos) {
+ // K007e=Pushback buffer full
throw new IOException(Msg.getString("K007e")); //$NON-NLS-1$
}
- // BEGIN android-changed
- if (buffer == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
+ // Force buffer null check first!
+ if (offset > buffer.length - length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // avoid int overflow
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // used (offset | count) < 0 instead of (offset < 0) || (count < 0)
- // to safe one operation
- if ((offset | count) < 0 || offset > buffer.length - count) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (length < 0) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
- // END android-changed
- for (int i = offset + count - 1; i >= offset; i--) {
+
+ for (int i = offset + length - 1; i >= offset; i--) {
unread(buffer[i]);
}
}
diff --git a/luni/src/main/java/java/io/StringBufferInputStream.java b/luni/src/main/java/java/io/StringBufferInputStream.java
index cc4ab81..037cc60 100644
--- a/luni/src/main/java/java/io/StringBufferInputStream.java
+++ b/luni/src/main/java/java/io/StringBufferInputStream.java
@@ -115,18 +115,19 @@
return -1;
}
if (b == null) {
+ // K0047=buffer is null
throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
}
// avoid int overflow
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, used (offset | length) < 0
- // instead of (offset < 0) || (length < 0) to safe one operation
- if ((offset | length) < 0 || length > b.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ if (offset < 0 || offset > b.length) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // END android-changed
+ if (length < 0 || length > b.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
+ }
+
if (length == 0) {
return 0;
}
diff --git a/luni/src/main/java/java/io/StringReader.java b/luni/src/main/java/java/io/StringReader.java
index 0a9e9bb..9f8671a 100644
--- a/luni/src/main/java/java/io/StringReader.java
+++ b/luni/src/main/java/java/io/StringReader.java
@@ -155,23 +155,19 @@
// BEGIN android-note
// changed array notation to be consistent with the rest of harmony
// END android-note
- // BEGIN android-changed
- // Exception priorities (in case of multiple errors) differ from
- // RI, but are spec-compliant.
- // removed redundant check, added null check, used (offset | len) < 0
- // instead of (offset < 0) || (len < 0) to safe one operation
- if (buf == null) {
- throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
- }
synchronized (lock) {
- // avoid int overflow
- if ((offset | len) < 0 || len > buf.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
- }
- // END android-changed
if (isClosed()) {
+ // K0083=StringReader is closed.
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
}
+ if (offset < 0 || offset > buf.length) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
+ }
+ if (len < 0 || len > buf.length - offset) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", len)); //$NON-NLS-1$
+ }
if (len == 0) {
return 0;
}
diff --git a/luni/src/main/java/java/lang/AbstractStringBuilder.java b/luni/src/main/java/java/lang/AbstractStringBuilder.java
index c481e11..869c694 100644
--- a/luni/src/main/java/java/lang/AbstractStringBuilder.java
+++ b/luni/src/main/java/java/lang/AbstractStringBuilder.java
@@ -120,21 +120,23 @@
count = newSize;
}
- final void append0(char chars[], int start, int length) {
- if (chars == null) {
- throw new NullPointerException();
+ final void append0(char[] chars, int offset, int length) {
+ // Force null check of chars first!
+ if (offset > chars.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // start + length could overflow, start/length maybe MaxInt
- if (start >= 0 && 0 <= length && length <= chars.length - start) {
- int newSize = count + length;
- if (newSize > value.length) {
- enlargeBuffer(newSize);
- }
- System.arraycopy(chars, start, value, count, length);
- count = newSize;
- } else {
- throw new ArrayIndexOutOfBoundsException();
+ if (length < 0 || chars.length - offset < length) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
+
+ int newSize = count + length;
+ if (newSize > value.length) {
+ enlargeBuffer(newSize);
+ }
+ System.arraycopy(chars, offset, value, count, length);
+ count = newSize;
}
final void append0(char ch) {
diff --git a/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java b/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
index d43a7e6..6bb67fc 100644
--- a/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
+++ b/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
@@ -44,6 +44,7 @@
* the invalid index.
*/
public ArrayIndexOutOfBoundsException(int index) {
+ // K0052=Array index out of range\: {0}
super(Msg.getString("K0052", index)); //$NON-NLS-1$
}
diff --git a/luni/src/main/java/java/lang/Enum.java b/luni/src/main/java/java/lang/Enum.java
index 395c825..e2ee32a 100644
--- a/luni/src/main/java/java/lang/Enum.java
+++ b/luni/src/main/java/java/lang/Enum.java
@@ -25,7 +25,7 @@
/**
* The superclass of all enumerated types. Actual enumeration types inherit from
- * this class, but extending this class does not make a class an enumration
+ * this class, but extending this class does not make a class an enumeration
* type, since the compiler needs to generate special information for it.
*/
public abstract class Enum<E extends Enum<E>> implements Serializable,
diff --git a/luni/src/main/java/java/lang/Integer.java b/luni/src/main/java/java/lang/Integer.java
index 570120b..5dcf217 100644
--- a/luni/src/main/java/java/lang/Integer.java
+++ b/luni/src/main/java/java/lang/Integer.java
@@ -526,7 +526,7 @@
int quot = positive_value;
do {
int res = quot / 10;
- int digit_value = quot - (res * 10);
+ int digit_value = quot - ((res << 3) + (res << 1));
digit_value += '0';
buffer[last_digit++] = (char) digit_value;
quot = res;
diff --git a/luni/src/main/java/java/lang/Math.java b/luni/src/main/java/java/lang/Math.java
index d06e6e4..f7b49b2 100644
--- a/luni/src/main/java/java/lang/Math.java
+++ b/luni/src/main/java/java/lang/Math.java
@@ -246,9 +246,7 @@
* the value whose closest integer value has to be computed.
* @return the ceiling of the argument.
*/
- // BEGIN android-changed
public static native double ceil(double d);
- // END android-changed
/**
* Returns the closest double approximation of the cosine of the argument.
@@ -348,9 +346,7 @@
* the value whose closest integer value has to be computed.
* @return the floor of the argument.
*/
- // BEGIN android-changed
public static native double floor(double d);
- // END android-changed
/**
* Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i>
@@ -731,9 +727,7 @@
* the value to be rounded.
* @return the closest integer to the argument (as a double).
*/
- // BEGIN android-changed
public static native double rint(double d);
- // END android-changed
/**
* Returns the result of rounding the argument to an integer. The result is
diff --git a/luni/src/main/java/java/lang/ProcessBuilder.java b/luni/src/main/java/java/lang/ProcessBuilder.java
index f649fec..245ed9c 100644
--- a/luni/src/main/java/java/lang/ProcessBuilder.java
+++ b/luni/src/main/java/java/lang/ProcessBuilder.java
@@ -191,24 +191,15 @@
* if an I/O error happens.
*/
public Process start() throws IOException {
- if (command.isEmpty()) {
- throw new IndexOutOfBoundsException();
- }
- String[] cmdArray = new String[command.size()];
- for (int i = 0; i < cmdArray.length; i++) {
- if ((cmdArray[i] = command.get(i)) == null) {
- throw new NullPointerException();
- }
- }
+ // BEGIN android-changed: push responsibility for argument checking into ProcessManager
+ String[] cmdArray = command.toArray(new String[command.size()]);
String[] envArray = new String[environment.size()];
int i = 0;
for (Map.Entry<String, String> entry : environment.entrySet()) {
envArray[i++] = entry.getKey() + "=" + entry.getValue(); //$NON-NLS-1$
}
- Process process = Runtime.getRuntime().exec(cmdArray, envArray,
- directory);
- // TODO implement support for redirectErrorStream
- return process;
+ return ProcessManager.getInstance().exec(cmdArray, envArray, directory, redirectErrorStream);
+ // END android-changed
}
private static List<String> toList(String[] strings) {
diff --git a/luni/src/main/java/java/lang/SecurityManager.java b/luni/src/main/java/java/lang/SecurityManager.java
index 9125850..8a04e92 100644
--- a/luni/src/main/java/java/lang/SecurityManager.java
+++ b/luni/src/main/java/java/lang/SecurityManager.java
@@ -414,9 +414,8 @@
.getSecurityProperty(property));
if (list != null) {
int plen = pkg.length();
- StringTokenizer tokenizer = new StringTokenizer(list, ", "); //$NON-NLS-1$
- while (tokenizer.hasMoreTokens()) {
- String token = tokenizer.nextToken();
+ String[] tokens = list.split(", *"); //$NON-NLS-1$
+ for (String token : tokens) {
int tlen = token.length();
if (plen > tlen
&& pkg.startsWith(token)
diff --git a/luni/src/main/java/java/net/DatagramSocketImpl.java b/luni/src/main/java/java/net/DatagramSocketImpl.java
index db3b9ec..12b2079 100644
--- a/luni/src/main/java/java/net/DatagramSocketImpl.java
+++ b/luni/src/main/java/java/net/DatagramSocketImpl.java
@@ -104,17 +104,6 @@
}
/**
- * Gets the value for the specified socket option.
- *
- * @param optID
- * the ID of the socket option to be retrieved.
- * @return the requested option value.
- * @throws SocketException
- * if an error occurs while accessing the option.
- */
- public abstract Object getOption(int optID) throws SocketException;
-
- /**
* Gets the time-to-live (TTL) for multicast packets sent on this socket.
*
* @return the time-to-live option as a byte value.
@@ -232,19 +221,6 @@
protected abstract void send(DatagramPacket pack) throws IOException;
/**
- * Sets the value for the specified socket option.
- *
- * @param optID
- * the ID of the socket option to be set.
- * @param val
- * the value of the option.
- * @throws SocketException
- * if an error occurs while setting the option.
- */
- public abstract void setOption(int optID, Object val)
- throws SocketException;
-
- /**
* Sets the time-to-live (TTL) option for multicast packets sent on this
* socket.
*
diff --git a/luni/src/main/java/java/net/InetAddress.java b/luni/src/main/java/java/net/InetAddress.java
index 33c25f3..e88d8b3 100644
--- a/luni/src/main/java/java/net/InetAddress.java
+++ b/luni/src/main/java/java/net/InetAddress.java
@@ -303,22 +303,18 @@
// BEGIN android-added
/**
- * Convenience method to convert a byte array to a string, converting
- * exceptions to runtime exceptions. This is used when passing in byte
- * arrays that have been verified to be correct and is necessary because
- * some methods, such as getHostName(), are not allowed to throw exceptions
- * but are implemented using byteArrayToIpString(), which throws
- * UnknownHostException. Exceptions should never occur when the address is
- * valid, but they cannot be simply ignored because they could be due to
- * runtime errors such as out-of-memory conditions.
+ * Returns the numeric string form of the given IP address.
*
- * @param ipaddress the byte array to convert
+ * @param ipAddress
+ * the byte array to convert; length 4 for IPv4, 16 for IPv6.
+ * @throws IllegalArgumentException
+ * if ipAddress is of length other than 4 or 16.
*/
- private static String ipAddressToString(byte[] ipaddress) {
+ private static String ipAddressToString(byte[] ipAddress) {
try {
- return NETIMPL.byteArrayToIpString(ipaddress);
- } catch(UnknownHostException e) {
- throw new RuntimeException(e);
+ return NETIMPL.byteArrayToIpString(ipAddress);
+ } catch (IOException ex) {
+ throw new IllegalArgumentException("byte[] neither 4 nor 16 bytes", ex);
}
}
// END android-added
@@ -1320,6 +1316,10 @@
family = fields.get("family", 2); //$NON-NLS-1$
}
+ /*
+ * The spec requires that if we encounter a generic InetAddress in
+ * serialized form then we should interpret it as an Inet4 address.
+ */
private Object readResolve() throws ObjectStreamException {
return new Inet4Address(ipaddress, hostName);
}
diff --git a/luni/src/main/java/java/net/JarURLConnection.java b/luni/src/main/java/java/net/JarURLConnection.java
index da39d9c..f41ef64 100644
--- a/luni/src/main/java/java/net/JarURLConnection.java
+++ b/luni/src/main/java/java/net/JarURLConnection.java
@@ -69,7 +69,7 @@
if ((sepIdx = file.indexOf("!/")) < 0) { //$NON-NLS-1$
throw new MalformedURLException();
}
- fileURL = new URL(url.getFile().substring(0,sepIdx)); //$NON-NLS-1$
+ fileURL = new URL(url.getFile().substring(0,sepIdx));
sepIdx += 2;
if (file.length() == sepIdx) {
return;
diff --git a/luni/src/main/java/java/net/NetworkInterface.java b/luni/src/main/java/java/net/NetworkInterface.java
index 091eb9f..f921b07 100644
--- a/luni/src/main/java/java/net/NetworkInterface.java
+++ b/luni/src/main/java/java/net/NetworkInterface.java
@@ -334,67 +334,66 @@
* the object to compare with this instance.
* @return {@code true} if the specified object is equal to this {@code
* NetworkInterface}, {@code false} otherwise.
- * @see #hashCode
+ * @see #hashCode()
*/
@Override
public boolean equals(Object obj) {
- // just return true if it is the exact same object
+ // Return true if it is the exact same object.
if (obj == this) {
return true;
}
- if (obj instanceof NetworkInterface) {
- /*
- * make sure that some simple checks pass. If the name is not the
- * same then we are sure it is not the same one. We don't check the
- * hashcode as it is generated from the name which we check
- */
- NetworkInterface netif = (NetworkInterface) obj;
-
- if (netif.getIndex() != interfaceIndex) {
- return false;
- }
-
- if (!(name.equals("")) && (!netif.getName().equals(name))) { //$NON-NLS-1$
- return false;
- }
-
- if ((name.equals("")) && (!netif.getName().equals(displayName))) { //$NON-NLS-1$
- return false;
- }
-
- // now check that the internet addresses are the same
- Enumeration<InetAddress> netifAddresses = netif.getInetAddresses();
- Enumeration<InetAddress> localifAddresses = getInetAddresses();
- if ((netifAddresses == null) && (localifAddresses != null)) {
- return false;
- }
-
- if ((netifAddresses == null) && (localifAddresses == null)) {
- // neither have any addresses so they are the same
- return true;
- }
-
- if (netifAddresses != null) {
- while (netifAddresses.hasMoreElements()
- && localifAddresses.hasMoreElements()) {
- if (!(localifAddresses.nextElement()).equals(netifAddresses
- .nextElement())) {
- return false;
- }
- }
- /*
- * now make sure that they had the same number of internet
- * addresses, if not they are not the same interface
- */
- if (netifAddresses.hasMoreElements()
- || localifAddresses.hasMoreElements()) {
- return false;
- }
- }
- return true;
+ // Ensure it is the right type.
+ if (!(obj instanceof NetworkInterface)) {
+ return false;
}
- return false;
+
+ /*
+ * Make sure that some simple checks pass. If the name is not the same
+ * then we are sure it is not the same one. We don't check the hashcode
+ * as it is generated from the name which we check
+ */
+ NetworkInterface netif = (NetworkInterface) obj;
+
+ if (netif.getIndex() != interfaceIndex) {
+ return false;
+ }
+
+ if (!(name.equals("")) && (!netif.getName().equals(name))) { //$NON-NLS-1$
+ return false;
+ }
+
+ if ((name.equals("")) && (!netif.getName().equals(displayName))) { //$NON-NLS-1$
+ return false;
+ }
+
+ // Now check that the collection of internet addresses are equal.
+ Enumeration<InetAddress> netifAddresses = netif.getInetAddresses();
+ Enumeration<InetAddress> localifAddresses = getInetAddresses();
+
+ // Check for both null (same), or one null (not same).
+ if (netifAddresses == null) {
+ return localifAddresses == null;
+ }
+ if (localifAddresses == null) {
+ return false;
+ }
+
+ // Both are not null, check InetAddress elements.
+ while (netifAddresses.hasMoreElements()
+ && localifAddresses.hasMoreElements()) {
+ if (!(localifAddresses.nextElement()).equals(
+ netifAddresses.nextElement())) {
+ return false;
+ }
+ }
+
+ /*
+ * Now make sure that they had the same number of addresses, if not they
+ * are not the same interface.
+ */
+ return !netifAddresses.hasMoreElements()
+ && !localifAddresses.hasMoreElements();
}
/**
diff --git a/luni/src/main/java/java/net/SocketAddress.java b/luni/src/main/java/java/net/SocketAddress.java
index 32a4c36..e84ebfd 100644
--- a/luni/src/main/java/java/net/SocketAddress.java
+++ b/luni/src/main/java/java/net/SocketAddress.java
@@ -26,6 +26,8 @@
*/
public abstract class SocketAddress implements Serializable {
+ private static final long serialVersionUID = 5215720748342549866L;
+
/**
* Creates a new {@code SocketAddress} instance.
*/
diff --git a/luni/src/main/java/java/net/URL.java b/luni/src/main/java/java/net/URL.java
index 9b0fdc4..b9e657d 100644
--- a/luni/src/main/java/java/net/URL.java
+++ b/luni/src/main/java/java/net/URL.java
@@ -889,15 +889,15 @@
protected void set(String protocol, String host, int port,
String authority, String userInfo, String path, String query,
String ref) {
- String file = path;
+ String filePart = path;
if (query != null && !query.equals("")) { //$NON-NLS-1$
- if (file != null) {
- file = file + "?" + query; //$NON-NLS-1$
+ if (filePart != null) {
+ filePart = filePart + "?" + query; //$NON-NLS-1$
} else {
- file = "?" + query; //$NON-NLS-1$
+ filePart = "?" + query; //$NON-NLS-1$
}
}
- set(protocol, host, port, file, ref);
+ set(protocol, host, port, filePart, ref);
this.authority = authority;
this.userInfo = userInfo;
this.path = path;
diff --git a/luni/src/main/java/java/net/URLClassLoader.java b/luni/src/main/java/java/net/URLClassLoader.java
index 6dfa385..61841e6 100644
--- a/luni/src/main/java/java/net/URLClassLoader.java
+++ b/luni/src/main/java/java/net/URLClassLoader.java
@@ -1167,7 +1167,7 @@
*/
private ArrayList<URL> getInternalURLs(URL root, String classpath) {
// Class-path attribute is composed of space-separated values.
- StringTokenizer tokenizer = new java.util.StringTokenizer(classpath);
+ StringTokenizer tokenizer = new StringTokenizer(classpath);
ArrayList<URL> addedURLs = new ArrayList<URL>();
String file = root.getFile();
int jarIndex = file.lastIndexOf("!/") - 1; //$NON-NLS-1$
@@ -1177,9 +1177,6 @@
System.getProperty("file.separator"), jarIndex) + 1; //$NON-NLS-1$
}
file = file.substring(0, index);
- String protocol = root.getProtocol();
- String host = root.getHost();
- int port = root.getPort();
while (tokenizer.hasMoreElements()) {
String element = tokenizer.nextToken();
if (!element.equals("")) { //$NON-NLS-1$
diff --git a/luni/src/main/java/java/util/ArrayList.java b/luni/src/main/java/java/util/ArrayList.java
index b8c7056..7c46e89 100644
--- a/luni/src/main/java/java/util/ArrayList.java
+++ b/luni/src/main/java/java/util/ArrayList.java
@@ -15,12 +15,16 @@
* limitations under the License.
*/
+// BEGIN android-note
+// New implementation: simpler and faster than Harmony implementation.
+// BEGIN android-note
+
package java.util;
import java.io.IOException;
+import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.ObjectStreamField;
import java.io.Serializable;
import java.lang.reflect.Array;
@@ -29,37 +33,38 @@
* optional operations adding, removing, and replacing are supported. The
* elements can be any objects.
*
+ * @param <E> The element type of this list.
* @since 1.2
*/
-public class ArrayList<E> extends AbstractList<E> implements List<E>,
- Cloneable, Serializable, RandomAccess {
-
- private static final long serialVersionUID = 8683452581122892189L;
-
- // BEGIN android-added
- /** zero-element array */
- private static final Object[] emptyArray = new Object[0];
- // END android-added
-
- private transient int firstIndex;
-
- private transient int lastIndex;
-
- private transient E[] array;
+public class ArrayList<E> extends AbstractList<E>
+ implements Cloneable, Serializable, RandomAccess {
+ /**
+ * An empty array of objects (to be shared among all empty lists).
+ */
+ private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
/**
- * Constructs a new instance of {@code ArrayList} with zero capacity.
+ * The minimum amount by which the capacity of an ArrayList will increase.
+ * This tuning parameter controls a time-space tradeoff. This value (12)
+ * gives empirically good results and is arguably consistent with the
+ * RI's specified default initial capacity of 10: instead of 10, we start
+ * with 0 (sans allocation) and jump to 12.
*/
- public ArrayList() {
- // BEGIN android-changed
- // default capacity is zero, not ten
- this(0);
- // END android-changed
- }
+ private static final int MIN_CAPACITY_INCREMENT = 12;
+
+ /**
+ * The number of elements in this list.
+ */
+ int size;
+
+ /**
+ * The elements in this list, followed by nulls.
+ */
+ transient Object[] array;
/**
* Constructs a new instance of {@code ArrayList} with the specified
- * capacity.
+ * initial capacity.
*
* @param capacity
* the initial capacity of this {@code ArrayList}.
@@ -68,84 +73,32 @@
if (capacity < 0) {
throw new IllegalArgumentException();
}
- firstIndex = lastIndex = 0;
- array = newElementArray(capacity);
+ array = (capacity == 0 ? EMPTY_OBJECT_ARRAY : new Object[capacity]);
+ }
+
+ /**
+ * Constructs a new {@code ArrayList} instance with zero initial capacity.
+ */
+ public ArrayList() {
+ array = EMPTY_OBJECT_ARRAY;
}
/**
* Constructs a new instance of {@code ArrayList} containing the elements of
- * the specified collection. The initial size of the {@code ArrayList} will
- * be 10% higher than the size of the specified collection.
+ * the specified collection.
*
* @param collection
* the collection of elements to add.
*/
public ArrayList(Collection<? extends E> collection) {
- firstIndex = 0;
- Object[] objects = collection.toArray();
- int size = objects.length;
- array = newElementArray(size + (size / 10));
- System.arraycopy(objects, 0, array, 0, size);
- lastIndex = size;
- modCount = 1;
- }
-
- @SuppressWarnings("unchecked")
- private E[] newElementArray(int size) {
- // BEGIN android-added
- if (size == 0) {
- return (E[])emptyArray;
+ Object[] a = collection.toArray();
+ if (a.getClass() != Object[].class) {
+ Object[] newArray = new Object[a.length];
+ System.arraycopy(a, 0, newArray, 0, a.length);
+ a = newArray;
}
- // END android-added
-
- return (E[]) new Object[size];
- }
-
- /**
- * Inserts the specified object into this {@code ArrayList} at the specified
- * location. The object is inserted before any previous element at the
- * specified location. If the location is equal to the size of this
- * {@code ArrayList}, the object is added at the end.
- *
- * @param location
- * the index at which to insert the object.
- * @param object
- * the object to add.
- * @throws IndexOutOfBoundsException
- * when {@code location < 0 || > size()}
- */
- @Override
- public void add(int location, E object) {
- int size = lastIndex - firstIndex;
- if (0 < location && location < size) {
- if (firstIndex == 0 && lastIndex == array.length) {
- growForInsert(location, 1);
- } else if ((location < size / 2 && firstIndex > 0)
- || lastIndex == array.length) {
- System.arraycopy(array, firstIndex, array, --firstIndex,
- location);
- } else {
- int index = location + firstIndex;
- System.arraycopy(array, index, array, index + 1, size
- - location);
- lastIndex++;
- }
- array[location + firstIndex] = object;
- } else if (location == 0) {
- if (firstIndex == 0) {
- growAtFront(1);
- }
- array[--firstIndex] = object;
- } else if (location == size) {
- if (lastIndex == array.length) {
- growAtEnd(1);
- }
- array[lastIndex++] = object;
- } else {
- throw new IndexOutOfBoundsException();
- }
-
- modCount++;
+ array = a;
+ size = a.length;
}
/**
@@ -155,80 +108,69 @@
* the object to add.
* @return always true
*/
- @Override
- public boolean add(E object) {
- if (lastIndex == array.length) {
- growAtEnd(1);
+ @Override public boolean add(E object) {
+ Object[] a = array;
+ int s = size;
+ if (s == a.length) {
+ Object[] newArray = new Object[s +
+ (s < (MIN_CAPACITY_INCREMENT / 2) ?
+ MIN_CAPACITY_INCREMENT : s >> 1)];
+ System.arraycopy(a, 0, newArray, 0, s);
+ array = a = newArray;
}
- array[lastIndex++] = object;
+ a[s] = object;
+ size = s + 1;
modCount++;
return true;
}
/**
- * Inserts the objects in the specified collection at the specified location
- * in this List. The objects are added in the order they are returned from
- * the collection's iterator.
+ * Inserts the specified object into this {@code ArrayList} at the specified
+ * location. The object is inserted before any previous element at the
+ * specified location. If the location is equal to the size of this
+ * {@code ArrayList}, the object is added at the end.
*
- * @param location
- * the index at which to insert.
- * @param collection
- * the collection of objects.
- * @return {@code true} if this {@code ArrayList} is modified, {@code false}
- * otherwise.
+ * @param index
+ * the index at which to insert the object.
+ * @param object
+ * the object to add.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || > size()}
*/
- @Override
- public boolean addAll(int location, Collection<? extends E> collection) {
- int size = lastIndex - firstIndex;
- if (location < 0 || location > size) {
- throw new IndexOutOfBoundsException();
- }
- if (this == collection) {
- collection = (ArrayList)clone();
- }
- Object[] dumparray = collection.toArray();
- int growSize = dumparray.length;
- if (growSize == 0) {
- return false;
+ @Override public void add(int index, E object) {
+ Object[] a = array;
+ int s = size;
+ if (index > s) {
+ throwIndexOutOfBoundsException(index, s);
}
- if (0 < location && location < size) {
- if (array.length - size < growSize) {
- growForInsert(location, growSize);
- } else if ((location < size / 2 && firstIndex > 0)
- || lastIndex > array.length - growSize) {
- int newFirst = firstIndex - growSize;
- if (newFirst < 0) {
- int index = location + firstIndex;
- System.arraycopy(array, index, array, index - newFirst,
- size - location);
- lastIndex -= newFirst;
- newFirst = 0;
- }
- System.arraycopy(array, firstIndex, array, newFirst, location);
- firstIndex = newFirst;
- } else {
- int index = location + firstIndex;
- System.arraycopy(array, index, array, index + growSize, size
- - location);
- lastIndex += growSize;
- }
- } else if (location == 0) {
- growAtFront(growSize);
- firstIndex -= growSize;
- } else if (location == size) {
- if (lastIndex > array.length - growSize) {
- growAtEnd(growSize);
- }
- lastIndex += growSize;
+ if (s < a.length) {
+ System.arraycopy(a, index, a, index + 1, s - index);
+ } else {
+ // assert s == a.length;
+ Object[] newArray = new Object[newCapacity(s)];
+ System.arraycopy(a, 0, newArray, 0, index);
+ System.arraycopy(a, index, newArray, index + 1, s - index);
+ array = a = newArray;
}
-
- System.arraycopy(dumparray, 0, this.array, location + firstIndex,
- growSize);
+ a[index] = object;
+ size = s + 1;
modCount++;
- return true;
+ }
+
+ /**
+ * This method controls the growth of ArrayList capacities. It represents
+ * a time-space tradeoff: we don't want to grow lists too frequently
+ * (which wastes time and fragments storage), but we don't want to waste
+ * too much space in unused excess capacity.
+ *
+ * NOTE: This method is inlined into {@link #add(Object)} for performance.
+ * If you change the method, change it there too!
+ */
+ private static int newCapacity(int currentCapacity) {
+ int increment = (currentCapacity < (MIN_CAPACITY_INCREMENT / 2) ?
+ MIN_CAPACITY_INCREMENT : currentCapacity >> 1);
+ return currentCapacity + increment;
}
/**
@@ -239,32 +181,85 @@
* @return {@code true} if this {@code ArrayList} is modified, {@code false}
* otherwise.
*/
- @Override
- public boolean addAll(Collection<? extends E> collection) {
- Object[] dumpArray = collection.toArray();
- if (dumpArray.length == 0) {
+ @Override public boolean addAll(Collection<? extends E> collection) {
+ Object[] newPart = collection.toArray();
+ int newPartSize = newPart.length;
+ if (newPartSize == 0) {
return false;
}
- if (dumpArray.length > array.length - lastIndex) {
- growAtEnd(dumpArray.length);
+ Object[] a = array;
+ int s = size;
+ int newSize = s + newPartSize; // If add overflows, arraycopy will fail
+ if (newSize > a.length) {
+ int newCapacity = newCapacity(newSize - 1); // ~33% growth room
+ Object[] newArray = new Object[newCapacity];
+ System.arraycopy(a, 0, newArray, 0, s);
+ array = a = newArray;
}
- System.arraycopy(dumpArray, 0, this.array, lastIndex, dumpArray.length);
- lastIndex += dumpArray.length;
+ System.arraycopy(newPart, 0, a, s, newPartSize);
+ size = newSize;
modCount++;
return true;
}
/**
+ * Inserts the objects in the specified collection at the specified location
+ * in this List. The objects are added in the order they are returned from
+ * the collection's iterator.
+ *
+ * @param index
+ * the index at which to insert.
+ * @param collection
+ * the collection of objects.
+ * @return {@code true} if this {@code ArrayList} is modified, {@code false}
+ * otherwise.
+ * @throws IndexOutOfBoundsException
+ * when {@code location < 0 || > size()}
+ */
+ @Override
+ public boolean addAll(int index, Collection<? extends E> collection) {
+ Object[] newPart = collection.toArray();
+ int newPartSize = newPart.length;
+ if (newPartSize == 0) {
+ return false;
+ }
+ Object[] a = array;
+ int s = size;
+ if (index > s) {
+ throwIndexOutOfBoundsException(index, s);
+ }
+ int newSize = s + newPartSize; // If add overflows, arraycopy will fail
+ if (newSize <= a.length) {
+ System.arraycopy(a, index, a, index + newPartSize, s - index);
+ } else {
+ int newCapacity = newCapacity(newSize - 1); // ~33% growth room
+ Object[] newArray = new Object[newCapacity];
+ System.arraycopy(a, 0, newArray, 0, index);
+ System.arraycopy(a, index, newArray, index + newPartSize, s-index);
+ array = a = newArray;
+ }
+ System.arraycopy(newPart, 0, a, index, newPartSize);
+ size = newSize;
+ modCount++;
+ return true;
+ }
+
+ /** This method was extracted to encourage VM to inline callers. */
+ private static void throwIndexOutOfBoundsException(int index, int size) {
+ throw new IndexOutOfBoundsException("Invalid index " + index
+ + ", size is " + size);
+ }
+
+ /**
* Removes all elements from this {@code ArrayList}, leaving it empty.
*
* @see #isEmpty
* @see #size
*/
- @Override
- public void clear() {
- if (firstIndex != lastIndex) {
- Arrays.fill(array, firstIndex, lastIndex, null);
- firstIndex = lastIndex = 0;
+ @Override public void clear() {
+ if (size != 0) {
+ Arrays.fill(array, 0, size, null);
+ size = 0;
modCount++;
}
}
@@ -276,45 +271,17 @@
* @return a shallow copy of this {@code ArrayList}
* @see java.lang.Cloneable
*/
- @Override
- @SuppressWarnings("unchecked")
- public Object clone() {
+ @Override public Object clone() {
try {
- ArrayList<E> newList = (ArrayList<E>) super.clone();
- newList.array = array.clone();
- return newList;
+ ArrayList<?> result = (ArrayList<?>) super.clone();
+ result.array = array.clone();
+ return result;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError();
}
}
/**
- * Searches this {@code ArrayList} for the specified object.
- *
- * @param object
- * the object to search for.
- * @return {@code true} if {@code object} is an element of this
- * {@code ArrayList}, {@code false} otherwise
- */
- @Override
- public boolean contains(Object object) {
- if (object != null) {
- for (int i = firstIndex; i < lastIndex; i++) {
- if (object.equals(array[i])) {
- return true;
- }
- }
- } else {
- for (int i = firstIndex; i < lastIndex; i++) {
- if (array[i] == null) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
* Ensures that after this operation the {@code ArrayList} can hold the
* specified number of elements without further growing.
*
@@ -322,145 +289,93 @@
* the minimum capacity asked for.
*/
public void ensureCapacity(int minimumCapacity) {
- if (array.length < minimumCapacity) {
- if (firstIndex > 0) {
- growAtFront(minimumCapacity - array.length);
- } else {
- growAtEnd(minimumCapacity - array.length);
- }
- }
- }
-
- @Override
- public E get(int location) {
- // BEGIN android-changed: slight performance improvement
- int _firstIndex = firstIndex;
- if (0 <= location && location < lastIndex - _firstIndex) {
- return array[_firstIndex + location];
- }
- throw new IndexOutOfBoundsException("Invalid location " + location
- + ", size is " + (lastIndex - _firstIndex));
- // END android-changed
- }
-
- private void growAtEnd(int required) {
- int size = lastIndex - firstIndex;
- if (firstIndex >= required - (array.length - lastIndex)) {
- int newLast = lastIndex - firstIndex;
- if (size > 0) {
- System.arraycopy(array, firstIndex, array, 0, size);
- int start = newLast < firstIndex ? firstIndex : newLast;
- Arrays.fill(array, start, array.length, null);
- }
- firstIndex = 0;
- lastIndex = newLast;
- } else {
- int increment = size / 2;
- if (required > increment) {
- increment = required;
- }
- if (increment < 12) {
- increment = 12;
- }
- E[] newArray = newElementArray(size + increment);
- if (size > 0) {
- System.arraycopy(array, firstIndex, newArray, 0, size);
- firstIndex = 0;
- lastIndex = size;
- }
+ Object[] a = array;
+ if (a.length < minimumCapacity) {
+ Object[] newArray = new Object[minimumCapacity];
+ System.arraycopy(a, 0, newArray, 0, size);
array = newArray;
+ modCount++;
}
}
- private void growAtFront(int required) {
- int size = lastIndex - firstIndex;
- if (array.length - lastIndex + firstIndex >= required) {
- int newFirst = array.length - size;
- if (size > 0) {
- System.arraycopy(array, firstIndex, array, newFirst, size);
- int length = firstIndex + size > newFirst ? newFirst
- : firstIndex + size;
- Arrays.fill(array, firstIndex, length, null);
- }
- firstIndex = newFirst;
- lastIndex = array.length;
- } else {
- int increment = size / 2;
- if (required > increment) {
- increment = required;
- }
- if (increment < 12) {
- increment = 12;
- }
- E[] newArray = newElementArray(size + increment);
- if (size > 0) {
- System.arraycopy(array, firstIndex, newArray, newArray.length
- - size, size);
- }
- firstIndex = newArray.length - size;
- lastIndex = newArray.length;
- array = newArray;
+ @SuppressWarnings("unchecked") @Override public E get(int index) {
+ if (index >= size) {
+ throwIndexOutOfBoundsException(index, size);
}
+ return (E) array[index];
}
- private void growForInsert(int location, int required) {
- int size = lastIndex - firstIndex;
- int increment = size / 2;
- if (required > increment) {
- increment = required;
- }
- if (increment < 12) {
- increment = 12;
- }
- E[] newArray = newElementArray(size + increment);
- int newFirst = increment - required;
- // Copy elements after location to the new array skipping inserted
- // elements
- System.arraycopy(array, location + firstIndex, newArray, newFirst
- + location + required, size - location);
- // Copy elements before location to the new array from firstIndex
- System.arraycopy(array, firstIndex, newArray, newFirst, location);
- firstIndex = newFirst;
- lastIndex = size + increment;
-
- array = newArray;
+ /**
+ * Returns the number of elements in this {@code ArrayList}.
+ *
+ * @return the number of elements in this {@code ArrayList}.
+ */
+ @Override public int size() {
+ return size;
}
- @Override
- public int indexOf(Object object) {
+ @Override public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Searches this {@code ArrayList} for the specified object.
+ *
+ * @param object
+ * the object to search for.
+ * @return {@code true} if {@code object} is an element of this
+ * {@code ArrayList}, {@code false} otherwise
+ */
+ @Override public boolean contains(Object object) {
+ Object[] a = array;
+ int s = size;
if (object != null) {
- for (int i = firstIndex; i < lastIndex; i++) {
- if (object.equals(array[i])) {
- return i - firstIndex;
+ for (int i = 0; i < s; i++) {
+ if (object.equals(a[i])) {
+ return true;
}
}
} else {
- for (int i = firstIndex; i < lastIndex; i++) {
- if (array[i] == null) {
- return i - firstIndex;
+ for (int i = 0; i < s; i++) {
+ if (a[i] == null) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override public int indexOf(Object object) {
+ Object[] a = array;
+ int s = size;
+ if (object != null) {
+ for (int i = 0; i < s; i++) {
+ if (object.equals(a[i])) {
+ return i;
+ }
+ }
+ } else {
+ for (int i = 0; i < s; i++) {
+ if (a[i] == null) {
+ return i;
}
}
}
return -1;
}
- @Override
- public boolean isEmpty() {
- return lastIndex == firstIndex;
- }
-
- @Override
- public int lastIndexOf(Object object) {
+ @Override public int lastIndexOf(Object object) {
+ Object[] a = array;
if (object != null) {
- for (int i = lastIndex - 1; i >= firstIndex; i--) {
- if (object.equals(array[i])) {
- return i - firstIndex;
+ for (int i = size - 1; i >= 0; i--) {
+ if (object.equals(a[i])) {
+ return i;
}
}
} else {
- for (int i = lastIndex - 1; i >= firstIndex; i--) {
- if (array[i] == null) {
- return i - firstIndex;
+ for (int i = size - 1; i >= 0; i--) {
+ if (a[i] == null) {
+ return i;
}
}
}
@@ -470,99 +385,81 @@
/**
* Removes the object at the specified location from this list.
*
- * @param location
+ * @param index
* the index of the object to remove.
* @return the removed object.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || >= size()}
*/
- @Override
- public E remove(int location) {
- E result;
- int size = lastIndex - firstIndex;
- if (0 <= location && location < size) {
- if (location == size - 1) {
- result = array[--lastIndex];
- array[lastIndex] = null;
- } else if (location == 0) {
- result = array[firstIndex];
- array[firstIndex++] = null;
- } else {
- int elementIndex = firstIndex + location;
- result = array[elementIndex];
- if (location < size / 2) {
- System.arraycopy(array, firstIndex, array, firstIndex + 1,
- location);
- array[firstIndex++] = null;
- } else {
- System.arraycopy(array, elementIndex + 1, array,
- elementIndex, size - location - 1);
- array[--lastIndex] = null;
- }
- }
- if (firstIndex == lastIndex) {
- firstIndex = lastIndex = 0;
- }
- } else {
- throw new IndexOutOfBoundsException();
+ @Override public E remove(int index) {
+ Object[] a = array;
+ int s = size;
+ if (index >= s) {
+ throwIndexOutOfBoundsException(index, s);
}
-
+ @SuppressWarnings("unchecked") E result = (E) a[index];
+ System.arraycopy(a, index + 1, a, index, --s - index);
+ a[s] = null; // Prevent memory leak
+ size = s;
modCount++;
return result;
}
- @Override
- public boolean remove(Object object) {
- int location = indexOf(object);
- if (location >= 0) {
- remove(location);
- return true;
+ @Override public boolean remove(Object object) {
+ Object[] a = array;
+ int s = size;
+ if (object != null) {
+ for (int i = 0; i < s; i++) {
+ if (object.equals(a[i])) {
+ System.arraycopy(a, i + 1, a, i, --s - i);
+ a[s] = null; // Prevent memory leak
+ size = s;
+ modCount++;
+ return true;
+ }
+ }
+ } else {
+ for (int i = 0; i < s; i++) {
+ if (a[i] == null) {
+ System.arraycopy(a, i + 1, a, i, --s - i);
+ a[s] = null; // Prevent memory leak
+ size = s;
+ modCount++;
+ return true;
+ }
+ }
}
return false;
}
- /**
- * Removes the objects in the specified range from the start to the end, but
- * not including the end index.
- *
- * @param start
- * the index at which to start removing.
- * @param end
- * the index one after the end of the range to remove.
- * @throws IndexOutOfBoundsException
- * when {@code start < 0, start > end} or {@code end > size()}
- */
- @Override
- protected void removeRange(int start, int end) {
- if (start >= 0 && start <= end && end <= (lastIndex - firstIndex)) {
- if (start == end) {
- return;
- }
- int size = lastIndex - firstIndex;
- if (end == size) {
- Arrays.fill(array, firstIndex + start, lastIndex, null);
- lastIndex = firstIndex + start;
- } else if (start == 0) {
- Arrays.fill(array, firstIndex, firstIndex + end, null);
- firstIndex += end;
- } else {
- System.arraycopy(array, firstIndex + end, array, firstIndex
- + start, size - end);
- int newLast = lastIndex + start - end;
- Arrays.fill(array, newLast, lastIndex, null);
- lastIndex = newLast;
- }
- modCount++;
- } else {
- throw new IndexOutOfBoundsException();
+ @Override protected void removeRange(int fromIndex, int toIndex) {
+ Object[] a = array;
+ int s = size;
+ if (fromIndex >= s) {
+ throw new IndexOutOfBoundsException("fromIndex " + fromIndex
+ + " >= size " + size);
}
+ if (toIndex > s) {
+ throw new IndexOutOfBoundsException("toIndex " + toIndex
+ + " > size " + size);
+ }
+ if (fromIndex > toIndex) {
+ throw new IndexOutOfBoundsException("fromIndex " + fromIndex
+ + " > toIndex " + toIndex);
+ }
+
+ System.arraycopy(a, toIndex, a, fromIndex, s - toIndex);
+ int rangeSize = toIndex - fromIndex;
+ Arrays.fill(a, s - rangeSize, s, null);
+ size = s - rangeSize;
+ modCount++;
}
/**
* Replaces the element at the specified location in this {@code ArrayList}
* with the specified object.
*
- * @param location
+ * @param index
* the index at which to put the specified object.
* @param object
* the object to add.
@@ -570,24 +467,14 @@
* @throws IndexOutOfBoundsException
* when {@code location < 0 || >= size()}
*/
- @Override
- public E set(int location, E object) {
- if (0 <= location && location < (lastIndex - firstIndex)) {
- E result = array[firstIndex + location];
- array[firstIndex + location] = object;
- return result;
+ @Override public E set(int index, E object) {
+ Object[] a = array;
+ if (index >= size) {
+ throwIndexOutOfBoundsException(index, size);
}
- throw new IndexOutOfBoundsException();
- }
-
- /**
- * Returns the number of elements in this {@code ArrayList}.
- *
- * @return the number of elements in this {@code ArrayList}.
- */
- @Override
- public int size() {
- return lastIndex - firstIndex;
+ @SuppressWarnings("unchecked") E result = (E) a[index];
+ a[index] = object;
+ return result;
}
/**
@@ -596,11 +483,10 @@
*
* @return an array of the elements from this {@code ArrayList}
*/
- @Override
- public Object[] toArray() {
- int size = lastIndex - firstIndex;
- Object[] result = new Object[size];
- System.arraycopy(array, firstIndex, result, 0, size);
+ @Override public Object[] toArray() {
+ int s = size;
+ Object[] result = new Object[s];
+ System.arraycopy(array, 0, result, 0, s);
return result;
}
@@ -619,17 +505,16 @@
* when the type of an element in this {@code ArrayList} cannot
* be stored in the type of the specified array.
*/
- @Override
- @SuppressWarnings("unchecked")
- public <T> T[] toArray(T[] contents) {
- int size = lastIndex - firstIndex;
- if (size > contents.length) {
- Class<?> ct = contents.getClass().getComponentType();
- contents = (T[]) Array.newInstance(ct, size);
+ @Override public <T> T[] toArray(T[] contents) {
+ int s = size;
+ if (contents.length < s) {
+ @SuppressWarnings("unchecked") T[] newArray
+ = (T[]) Array.newInstance(contents.getClass().getComponentType(), s);
+ contents = newArray;
}
- System.arraycopy(array, firstIndex, contents, 0, size);
- if (size < contents.length) {
- contents[size] = null;
+ System.arraycopy(this.array, 0, contents, 0, s);
+ if (contents.length > s) {
+ contents[s] = null;
}
return contents;
}
@@ -641,37 +526,132 @@
* @see #size
*/
public void trimToSize() {
- int size = lastIndex - firstIndex;
- E[] newArray = newElementArray(size);
- System.arraycopy(array, firstIndex, newArray, 0, size);
- array = newArray;
- firstIndex = 0;
- lastIndex = array.length;
- modCount = 0;
+ int s = size;
+ if (s == array.length) {
+ return;
+ }
+ if (s == 0) {
+ array = EMPTY_OBJECT_ARRAY;
+ } else {
+ Object[] newArray = new Object[s];
+ System.arraycopy(array, 0, newArray, 0, s);
+ array = newArray;
+ }
+ modCount++;
}
- private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
- "size", Integer.TYPE) }; //$NON-NLS-1$
+ @Override public Iterator<E> iterator() {
+ return new ArrayListIterator();
+ }
+
+ private class ArrayListIterator implements Iterator<E> {
+ /** Number of elements remaining in this iteration */
+ private int remaining = size;
+
+ /** Index of element that remove() would remove, or -1 if no such elt */
+ private int removalIndex = -1;
+
+ /** The expected modCount value */
+ private int expectedModCount = modCount;
+
+ public boolean hasNext() {
+ return remaining != 0;
+ }
+
+ @SuppressWarnings("unchecked") public E next() {
+ ArrayList<E> ourList = ArrayList.this;
+ int rem = remaining;
+ if (ourList.modCount != expectedModCount) {
+ throw new ConcurrentModificationException();
+ }
+ if (rem == 0) {
+ throw new NoSuchElementException();
+ }
+ remaining = rem - 1;
+ return (E) ourList.array[removalIndex = ourList.size - rem];
+ }
+
+ public void remove() {
+ Object[] a = array;
+ int removalIdx = removalIndex;
+ if (modCount != expectedModCount) {
+ throw new ConcurrentModificationException();
+ }
+ if (removalIdx < 0) {
+ throw new IllegalStateException();
+ }
+ System.arraycopy(a, removalIdx + 1, a, removalIdx, remaining);
+ a[--size] = null; // Prevent memory leak
+ removalIndex = -1;
+ expectedModCount = ++modCount;
+ }
+ }
+
+ @Override public int hashCode() {
+ Object[] a = array;
+ int hashCode = 1;
+ for (int i = 0, s = size; i < s; i++) {
+ Object e = a[i];
+ hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
+ }
+ return hashCode;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof List)) {
+ return false;
+ }
+ List<?> that = (List<?>) o;
+ int s = size;
+ if (that.size() != s) {
+ return false;
+ }
+ Object[] a = array;
+ if (that instanceof RandomAccess) {
+ for (int i = 0; i < s; i++) {
+ Object eThis = a[i];
+ Object ethat = that.get(i);
+ if (eThis == null ? ethat != null : !eThis.equals(ethat)) {
+ return false;
+ }
+ }
+ } else { // Argument list is not random access; use its iterator
+ Iterator<?> it = that.iterator();
+ for (int i = 0; i < s; i++) {
+ Object eThis = a[i];
+ Object eThat = it.next();
+ if (eThis == null ? eThat != null : !eThis.equals(eThat)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private static final long serialVersionUID = 8683452581122892189L;
private void writeObject(ObjectOutputStream stream) throws IOException {
- ObjectOutputStream.PutField fields = stream.putFields();
- fields.put("size", lastIndex - firstIndex); //$NON-NLS-1$
- stream.writeFields();
+ stream.defaultWriteObject();
stream.writeInt(array.length);
- Iterator<?> it = iterator();
- while (it.hasNext()) {
- stream.writeObject(it.next());
+ for (int i = 0; i < size; i++) {
+ stream.writeObject(array[i]);
}
}
- @SuppressWarnings("unchecked")
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
- ObjectInputStream.GetField fields = stream.readFields();
- lastIndex = fields.get("size", 0); //$NON-NLS-1$
- array = newElementArray(stream.readInt());
- for (int i = 0; i < lastIndex; i++) {
- array[i] = (E) stream.readObject();
+ stream.defaultReadObject();
+ int cap = stream.readInt();
+ if (cap < size) {
+ throw new InvalidObjectException(
+ "Capacity: " + cap + " < size: " + size);
+ }
+ array = (cap == 0 ? EMPTY_OBJECT_ARRAY : new Object[cap]);
+ for (int i = 0; i < size; i++) {
+ array[i] = stream.readObject();
}
}
-}
+ }
diff --git a/luni/src/main/java/java/util/Arrays.java b/luni/src/main/java/java/util/Arrays.java
index 4fc1e85..b6a4ec5 100644
--- a/luni/src/main/java/java/util/Arrays.java
+++ b/luni/src/main/java/java/util/Arrays.java
@@ -20,6 +20,8 @@
import java.io.Serializable;
import java.lang.reflect.Array;
+import org.apache.harmony.luni.util.Msg;
+
/**
* {@code Arrays} contains static methods which operate on arrays.
*
@@ -492,14 +494,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(byte[] array, int start, int end, byte value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -536,14 +531,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(short[] array, int start, int end, short value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -580,14 +568,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(char[] array, int start, int end, char value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -624,14 +605,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(int[] array, int start, int end, int value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -668,14 +642,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(long[] array, int start, int end, long value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -712,14 +679,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(float[] array, int start, int end, float value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -756,14 +716,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(double[] array, int start, int end, double value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -800,14 +753,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(boolean[] array, int start, int end, boolean value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -844,14 +790,7 @@
* if {@code start < 0} or {@code end > array.length}.
*/
public static void fill(Object[] array, int start, int end, Object value) {
- // Check for null first
- int length = array.length;
- if (start > end) {
- throw new IllegalArgumentException();
- }
- if (start < 0 || end > length) {
- throw new ArrayIndexOutOfBoundsException();
- }
+ checkBounds(array.length, start, end);
for (int i = start; i < end; i++) {
array[i] = value;
}
@@ -1690,11 +1629,17 @@
private static void checkBounds(int arrLength, int start, int end) {
if (start > end) {
- throw new IllegalArgumentException("start(" + start //$NON-NLS-1$
- + ") > end(" + end + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ // K0033=Start index ({0}) is greater than end index ({1})
+ throw new IllegalArgumentException(Msg.getString("K0033", //$NON-NLS-1$
+ Integer.valueOf(start), Integer.valueOf(end)));
}
- if (start < 0 || end > arrLength) {
- throw new ArrayIndexOutOfBoundsException();
+ if (start < 0) {
+ // K0052=Array index out of range\: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0052", start)); //$NON-NLS-1$
+ }
+ if (end > arrLength) {
+ // K0052=Array index out of range\: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0052", end)); //$NON-NLS-1$
}
}
@@ -2630,7 +2575,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 5);
+ StringBuilder sb = new StringBuilder(array.length * 7); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2660,7 +2605,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 3);
+ StringBuilder sb = new StringBuilder(array.length * 6); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2690,7 +2635,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 2);
+ StringBuilder sb = new StringBuilder(array.length * 3); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2720,7 +2665,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 5);
+ StringBuilder sb = new StringBuilder(array.length * 7); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2750,7 +2695,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 5);
+ StringBuilder sb = new StringBuilder(array.length * 7); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2780,7 +2725,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 4);
+ StringBuilder sb = new StringBuilder(array.length * 6); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2810,7 +2755,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 4);
+ StringBuilder sb = new StringBuilder(array.length * 6); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2840,7 +2785,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 4);
+ StringBuilder sb = new StringBuilder(array.length * 6); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2870,7 +2815,7 @@
if (array.length == 0) {
return "[]"; //$NON-NLS-1$
}
- StringBuilder sb = new StringBuilder(2 + array.length * 5);
+ StringBuilder sb = new StringBuilder(array.length * 7); // android-changed
sb.append('[');
sb.append(array[0]);
for (int i = 1; i < array.length; i++) {
@@ -2904,7 +2849,7 @@
return "null"; //$NON-NLS-1$
}
// delegate this to the recursive method
- StringBuilder buf = new StringBuilder(2 + array.length * 5);
+ StringBuilder buf = new StringBuilder(array.length * 9); // android-changed
deepToStringImpl(array, new Object[] { array }, buf);
return buf.toString();
}
diff --git a/luni/src/main/java/java/util/BitSet.java b/luni/src/main/java/java/util/BitSet.java
index 4e01cbf..f88ca7d 100644
--- a/luni/src/main/java/java/util/BitSet.java
+++ b/luni/src/main/java/java/util/BitSet.java
@@ -131,7 +131,7 @@
clone.bits = bits.clone();
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/Calendar.java b/luni/src/main/java/java/util/Calendar.java
index 0ac574c..49a8c3f 100644
--- a/luni/src/main/java/java/util/Calendar.java
+++ b/luni/src/main/java/java/util/Calendar.java
@@ -790,7 +790,7 @@
clone.zone = (TimeZone) zone.clone();
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/Collection.java b/luni/src/main/java/java/util/Collection.java
index 6447e39..1b5cff5 100644
--- a/luni/src/main/java/java/util/Collection.java
+++ b/luni/src/main/java/java/util/Collection.java
@@ -24,7 +24,7 @@
* of {@code Collection}s.
*
* All direct or indirect implementations of {@code Collection} should implement at
- * least two constuctors. One with no parameters which creates an empty
+ * least two constructors. One with no parameters which creates an empty
* collection and one with a parameter of type {@code Collection}. This second
* constructor can be used to create a collection of different type as the
* initial collection but with the same elements. Implementations of {@code Collection}
@@ -138,7 +138,7 @@
/**
* Tests whether this {@code Collection} contains all objects contained in the
- * specified {@code Collection}. If an elemenet {@code elem} is contained several
+ * specified {@code Collection}. If an element {@code elem} is contained several
* times in the specified {@code Collection}, the method returns {@code true} even
* if {@code elem} is contained only once in this {@code Collection}.
*
diff --git a/luni/src/main/java/java/util/Collections.java b/luni/src/main/java/java/util/Collections.java
index 767d98b..77cafea 100644
--- a/luni/src/main/java/java/util/Collections.java
+++ b/luni/src/main/java/java/util/Collections.java
@@ -23,6 +23,7 @@
import java.lang.reflect.Array;
import org.apache.harmony.luni.internal.nls.Messages;
+import org.apache.harmony.luni.util.Msg;
/**
* {@code Collections} contains static methods which operate on
@@ -1590,7 +1591,8 @@
public static <T> void copy(List<? super T> destination,
List<? extends T> source) {
if (destination.size() < source.size()) {
- throw new ArrayIndexOutOfBoundsException();
+ // K0032=Source size {0} does not fit into destination
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0032", source.size())); //$NON-NLS-1$
}
Iterator<? extends T> srcIt = source.iterator();
ListIterator<? super T> destIt = destination.listIterator();
@@ -1598,7 +1600,8 @@
try {
destIt.next();
} catch (NoSuchElementException e) {
- throw new ArrayIndexOutOfBoundsException();
+ // K0032=Source size {0} does not fit into destination
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0032", source.size())); //$NON-NLS-1$
}
destIt.set(srcIt.next());
}
@@ -1841,36 +1844,30 @@
* @throws UnsupportedOperationException
* when replacing an element in the list is not supported.
*/
- @SuppressWarnings("unchecked")
public static void shuffle(List<?> list, Random random) {
- if (!(list instanceof RandomAccess)) {
- Object[] array = list.toArray();
+ @SuppressWarnings("unchecked") // we won't put foreign objects in
+ final List<Object> objectList = (List<Object>) list;
+
+ if (list instanceof RandomAccess) {
+ for (int i = objectList.size() - 1; i > 0; i--) {
+ int index = random.nextInt(i + 1);
+ objectList.set(index, objectList.set(i, objectList.get(index)));
+ }
+ } else {
+ Object[] array = objectList.toArray();
for (int i = array.length - 1; i > 0; i--) {
int index = random.nextInt(i + 1);
- if (index < 0) {
- index = -index;
- }
Object temp = array[i];
array[i] = array[index];
array[index] = temp;
}
int i = 0;
- ListIterator<Object> it = (ListIterator<Object>) list
- .listIterator();
+ ListIterator<Object> it = objectList.listIterator();
while (it.hasNext()) {
it.next();
it.set(array[i++]);
}
- } else {
- List<Object> rawList = (List<Object>) list;
- for (int i = rawList.size() - 1; i > 0; i--) {
- int index = random.nextInt(i + 1);
- if (index < 0) {
- index = -index;
- }
- rawList.set(index, rawList.set(i, rawList.get(index)));
- }
}
}
diff --git a/luni/src/main/java/java/util/Date.java b/luni/src/main/java/java/util/Date.java
index 80610d3..37f5b6a 100644
--- a/luni/src/main/java/java/util/Date.java
+++ b/luni/src/main/java/java/util/Date.java
@@ -193,7 +193,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/EnumMap.java b/luni/src/main/java/java/util/EnumMap.java
index 975fdad..2b33175 100644
--- a/luni/src/main/java/java/util/EnumMap.java
+++ b/luni/src/main/java/java/util/EnumMap.java
@@ -470,7 +470,7 @@
enumMap.initialization(this);
return enumMap;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/EnumSet.java b/luni/src/main/java/java/util/EnumSet.java
index d49d900..c2c3fc0 100644
--- a/luni/src/main/java/java/util/EnumSet.java
+++ b/luni/src/main/java/java/util/EnumSet.java
@@ -322,7 +322,7 @@
Object set = super.clone();
return (EnumSet<E>) set;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/Formatter.java b/luni/src/main/java/java/util/Formatter.java
index d1dd417..912a15e 100644
--- a/luni/src/main/java/java/util/Formatter.java
+++ b/luni/src/main/java/java/util/Formatter.java
@@ -885,7 +885,6 @@
if (transformer == null || ! transformer.locale.equals(l)) {
transformer = new Transformer(this, l);
}
- // END android-changed
int currentObjectIndex = 0;
Object lastArgument = null;
@@ -893,12 +892,13 @@
while (formatBuffer.hasRemaining()) {
parser.reset();
FormatToken token = parser.getNextFormatToken();
- String result;
String plainText = token.getPlainText();
if (token.getConversionType() == (char) FormatToken.UNSET) {
- result = plainText;
+ outputCharSequence(plainText);
} else {
plainText = plainText.substring(0, plainText.indexOf('%'));
+ outputCharSequence(plainText);
+
Object argument = null;
if (token.requireArgument()) {
int index = token.getArgIndex() == FormatToken.UNSET ? currentObjectIndex++
@@ -908,21 +908,26 @@
lastArgument = argument;
hasLastArgumentSet = true;
}
- result = transformer.transform(token, argument);
- result = (null == result ? plainText : plainText + result);
- }
- // if output is made by formattable callback
- if (null != result) {
- try {
- out.append(result);
- } catch (IOException e) {
- lastIOException = e;
- }
+ outputCharSequence(transformer.transform(token, argument));
}
}
+ // END android-changed
return this;
}
+ // BEGIN android-added
+ // Fixes http://code.google.com/p/android/issues/detail?id=1767.
+ private void outputCharSequence(CharSequence cs) {
+ if (cs != null) {
+ try {
+ out.append(cs);
+ } catch (IOException e) {
+ lastIOException = e;
+ }
+ }
+ }
+ // END android-added
+
private Object getArgument(Object[] args, int index, FormatToken token,
Object lastArgument, boolean hasLastArgumentSet) {
if (index == FormatToken.LAST_ARGUMENT_INDEX && !hasLastArgumentSet) {
@@ -1184,13 +1189,13 @@
* Gets the formatted string according to the format token and the
* argument.
*/
- String transform(FormatToken token, Object argument) {
+ CharSequence transform(FormatToken token, Object argument) {
/* init data member to print */
this.formatToken = token;
this.arg = argument;
- String result;
+ CharSequence result;
switch (token.getConversionType()) {
case 'B':
case 'b': {
@@ -1254,7 +1259,7 @@
if (Character.isUpperCase(token.getConversionType())) {
if (null != result) {
- result = result.toUpperCase(Locale.US);
+ result = result.toString().toUpperCase(Locale.US);
}
}
return result;
@@ -1263,7 +1268,7 @@
/*
* Transforms the Boolean argument to a formatted string.
*/
- private String transformFromBoolean() {
+ private CharSequence transformFromBoolean() {
StringBuilder result = new StringBuilder();
int startIndex = 0;
int flags = formatToken.getFlags();
@@ -1294,7 +1299,7 @@
/*
* Transforms the hashcode of the argument to a formatted string.
*/
- private String transformFromHashCode() {
+ private CharSequence transformFromHashCode() {
StringBuilder result = new StringBuilder();
int startIndex = 0;
@@ -1324,7 +1329,7 @@
/*
* Transforms the String to a formatted string.
*/
- private String transformFromString() {
+ private CharSequence transformFromString() {
StringBuilder result = new StringBuilder();
int startIndex = 0;
int flags = formatToken.getFlags();
@@ -1374,7 +1379,7 @@
/*
* Transforms the Character to a formatted string.
*/
- private String transformFromCharacter() {
+ private CharSequence transformFromCharacter() {
StringBuilder result = new StringBuilder();
int startIndex = 0;
@@ -1434,7 +1439,7 @@
* Transforms percent to a formatted string. Only '-' is legal flag.
* Precision is illegal.
*/
- private String transformFromPercent() {
+ private CharSequence transformFromPercent() {
StringBuilder result = new StringBuilder("%"); //$NON-NLS-1$
int startIndex = 0;
@@ -1462,7 +1467,7 @@
* Transforms line separator to a formatted string. Any flag, the width
* or the precision is illegal.
*/
- private String transformFromLineSeparator() {
+ private CharSequence transformFromLineSeparator() {
if (formatToken.isPrecisionSet()) {
throw new IllegalFormatPrecisionException(formatToken
.getPrecision());
@@ -1492,7 +1497,7 @@
/*
* Pads characters to the formatted string.
*/
- private String padding(StringBuilder source, int startIndex) {
+ private CharSequence padding(StringBuilder source, int startIndex) {
int start = startIndex;
boolean paddingRight = formatToken
.isFlagSet(FormatToken.FLAG_MINUS);
@@ -1520,7 +1525,7 @@
width = Math.max(source.length(), width);
}
if (length >= width) {
- return source.toString();
+ return source;
}
char[] paddings = new char[width - length];
@@ -1532,13 +1537,13 @@
} else {
source.insert(start, insertString);
}
- return source.toString();
+ return source;
}
/*
* Transforms the Integer to a formatted string.
*/
- private String transformFromInteger() {
+ private CharSequence transformFromInteger() {
int startIndex = 0;
boolean isNegative = false;
StringBuilder result = new StringBuilder();
@@ -1651,7 +1656,7 @@
if (isNegative
&& formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
result = wrapParentheses(result);
- return result.toString();
+ return result;
}
if (isNegative && formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
@@ -1680,7 +1685,7 @@
return result;
}
- private String transformFromSpecialNumber() {
+ private CharSequence transformFromSpecialNumber() {
String source = null;
if (!(arg instanceof Number) || arg instanceof BigDecimal) {
@@ -1713,12 +1718,12 @@
formatToken.setPrecision(FormatToken.UNSET);
formatToken.setFlags(formatToken.getFlags()
& (~FormatToken.FLAG_ZERO));
- source = padding(new StringBuilder(source), 0);
+ return padding(new StringBuilder(source), 0);
}
return source;
}
- private String transformFromNull() {
+ private CharSequence transformFromNull() {
formatToken.setFlags(formatToken.getFlags()
& (~FormatToken.FLAG_ZERO));
return padding(new StringBuilder("null"), 0); //$NON-NLS-1$
@@ -1727,7 +1732,7 @@
/*
* Transforms a BigInteger to a formatted string.
*/
- private String transformFromBigInteger() {
+ private CharSequence transformFromBigInteger() {
int startIndex = 0;
boolean isNegative = false;
StringBuilder result = new StringBuilder();
@@ -1817,7 +1822,7 @@
if (isNegative
&& formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
result = wrapParentheses(result);
- return result.toString();
+ return result;
}
if (isNegative && formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
@@ -1829,7 +1834,7 @@
/*
* Transforms a Float,Double or BigDecimal to a formatted string.
*/
- private String transformFromFloat() {
+ private CharSequence transformFromFloat() {
StringBuilder result = new StringBuilder();
int startIndex = 0;
char currentConversionType = formatToken.getConversionType();
@@ -1883,7 +1888,7 @@
currentConversionType, arg.getClass());
}
- String specialNumberResult = transformFromSpecialNumber();
+ CharSequence specialNumberResult = transformFromSpecialNumber();
if (null != specialNumberResult) {
return specialNumberResult;
}
@@ -1896,7 +1901,7 @@
}
// output result
FloatUtil floatUtil = new FloatUtil(result, formatToken,
- (DecimalFormat) NumberFormat.getInstance(locale), arg);
+ (DecimalFormat) getNumberFormat(), arg);
floatUtil.transform(formatToken, result);
formatToken.setPrecision(FormatToken.UNSET);
@@ -1904,7 +1909,7 @@
if (getDecimalFormatSymbols().getMinusSign() == result.charAt(0)) {
if (formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
result = wrapParentheses(result);
- return result.toString();
+ return result;
}
} else {
if (formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
@@ -1933,7 +1938,7 @@
/*
* Transforms a Date to a formatted string.
*/
- private String transformFromDateTime() {
+ private CharSequence transformFromDateTime() {
int startIndex = 0;
char currentConversionType = formatToken.getConversionType();
@@ -2110,18 +2115,15 @@
} else {
l = b.movePointRight(4).longValue();
- b.movePointLeft(4);
if (d >= Math.pow(10, -4) && d < 1) {
requireScientificRepresentation = false;
precision += 4 - String.valueOf(l).length();
l = b.movePointRight(precision + 1).longValue();
- b.movePointLeft(precision + 1);
if (String.valueOf(l).length() <= formatToken
.getPrecision()) {
precision++;
}
l = b.movePointRight(precision).longValue();
- b.movePointLeft(precision);
if (l >= Math.pow(10, precision - 4)) {
formatToken.setPrecision(precision);
}
diff --git a/luni/src/main/java/java/util/GregorianCalendar.java b/luni/src/main/java/java/util/GregorianCalendar.java
index d8cd556..7339151 100644
--- a/luni/src/main/java/java/util/GregorianCalendar.java
+++ b/luni/src/main/java/java/util/GregorianCalendar.java
@@ -533,7 +533,6 @@
fields[MINUTE] = (millis % 60);
millis /= 60;
fields[HOUR_OF_DAY] = (millis % 24);
- millis /= 24;
fields[AM_PM] = fields[HOUR_OF_DAY] > 11 ? 1 : 0;
fields[HOUR] = fields[HOUR_OF_DAY] % 12;
diff --git a/luni/src/main/java/java/util/HashMap.java b/luni/src/main/java/java/util/HashMap.java
index 28978d4..f79601f 100644
--- a/luni/src/main/java/java/util/HashMap.java
+++ b/luni/src/main/java/java/util/HashMap.java
@@ -36,7 +36,7 @@
* @param <V> the type of mapped values
*/
public class HashMap<K, V> extends AbstractMap<K, V>
- implements Cloneable, Serializable, Map<K, V> {
+ implements Cloneable, Serializable {
/**
* Min capacity (other than zero) for a HashMap. Must be a power of two
* greater than 1 (and less than 1 << 30).
diff --git a/luni/src/main/java/java/util/HashSet.java b/luni/src/main/java/java/util/HashSet.java
index 4c97ca5..aa5c3fb 100644
--- a/luni/src/main/java/java/util/HashSet.java
+++ b/luni/src/main/java/java/util/HashSet.java
@@ -121,7 +121,7 @@
clone.backingMap = (HashMap<E, HashSet<E>>) backingMap.clone();
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/IdentityHashMap.java b/luni/src/main/java/java/util/IdentityHashMap.java
index 053de1d..8d0f036 100644
--- a/luni/src/main/java/java/util/IdentityHashMap.java
+++ b/luni/src/main/java/java/util/IdentityHashMap.java
@@ -758,7 +758,7 @@
elementData.length);
return cloneHashMap;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/LinkedList.java b/luni/src/main/java/java/util/LinkedList.java
index 64326e3..7a7e81f 100644
--- a/luni/src/main/java/java/util/LinkedList.java
+++ b/luni/src/main/java/java/util/LinkedList.java
@@ -402,7 +402,7 @@
l.addAll(this);
return l;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index b1a1821..22cda76 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -48,7 +48,9 @@
private static final long serialVersionUID = 9149081749638150636L;
+ // BEGIN android-added
private static volatile Locale[] availableLocales;
+ // END android-added
// Initialize a default which is used during static
// initialization of the default for the platform.
@@ -275,7 +277,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
@@ -304,93 +306,6 @@
return false;
}
- // BEGIN android-removed
- // static Locale[] find(String prefix) {
- // int last = prefix.lastIndexOf('/');
- // final String thePackage = prefix.substring(0, last + 1);
- // int length = prefix.length();
- // final String classPrefix = prefix.substring(last + 1, length);
- // Set<String> result = new HashSet<String>();
- // StringTokenizer paths = new StringTokenizer(System.getProperty(
- // "org.apache.harmony.boot.class.path", ""), System.getProperty( //$NON-NLS-1$ //$NON-NLS-2$
- // "path.separator", ";")); //$NON-NLS-1$//$NON-NLS-2$
- // while (paths.hasMoreTokens()) {
- // String nextToken = paths.nextToken();
- // File directory = new File(nextToken);
- // if (directory.exists()) {
- // if (directory.isDirectory()) {
- // String path;
- // try {
- // path = directory.getCanonicalPath();
- // } catch (IOException e) {
- // continue;
- // }
- // File newDir;
- // if (path.charAt(path.length() - 1) == File.separatorChar) {
- // newDir = new File(path + thePackage);
- // } else {
- // newDir = new File(path + File.separatorChar
- // + thePackage);
- // }
- // if (newDir.isDirectory()) {
- // String[] list = newDir.list();
- // for (int i = 0; i < list.length; i++) {
- // String name = list[i];
- // if (name.startsWith(classPrefix)
- // && name.endsWith(".class")) { //$NON-NLS-1$
- // result
- // .add(name.substring(0,
- // name.length() - 6));
- // }
- // }
- // }
- //
- // } else {
- // // Handle ZIP/JAR files.
- // try {
- // ZipFile zip = new ZipFile(directory);
- // Enumeration<? extends ZipEntry> entries = zip.entries();
- // while (entries.hasMoreElements()) {
- // ZipEntry e = entries.nextElement();
- // String name = e.getName();
- // if (name.startsWith(prefix)
- // && name.endsWith(".class")) {//$NON-NLS-1$
- // result.add(name.substring(last + 1, name
- // .length() - 6));
- // }
- // }
- // zip.close();
- // } catch (IOException e) {
- // // Empty
- // }
- // }
- // }
- // }
- // Locale[] locales = new Locale[result.size()];
- // int i = 0;
- // for (String name : result) {
- // int index = name.indexOf('_');
- // int nextIndex = name.indexOf('_', index + 1);
- // if (nextIndex == -1) {
- // locales[i++] = new Locale(name.substring(index + 1, name
- // .length()), ""); //$NON-NLS-1$
- // } else {
- // String language = name.substring(index + 1, nextIndex);
- // String variant;
- // if ((index = name.indexOf('_', nextIndex + 1)) == -1) {
- // variant = ""; //$NON-NLS-1$
- // index = name.length();
- // } else {
- // variant = name.substring(index + 1, name.length());
- // }
- // String country = name.substring(nextIndex + 1, index);
- // locales[i++] = new Locale(language, country, variant);
- // }
- // }
- // return locales;
- // }
- // END android-removed
-
// BEGIN android-added
static Locale[] find() {
String[] locales = Resources.getAvailableLocales();
diff --git a/luni/src/main/java/java/util/MapEntry.java b/luni/src/main/java/java/util/MapEntry.java
index 6a5bf0f..b84697b 100644
--- a/luni/src/main/java/java/util/MapEntry.java
+++ b/luni/src/main/java/java/util/MapEntry.java
@@ -43,7 +43,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/Random.java b/luni/src/main/java/java/util/Random.java
index be27258..f893020 100644
--- a/luni/src/main/java/java/util/Random.java
+++ b/luni/src/main/java/java/util/Random.java
@@ -52,15 +52,22 @@
*/
private double nextNextGaussian;
+ // BEGIN android-changed
/**
- * Construct a random generator with the current time of day in milliseconds
- * as the initial state.
+ * Constructs a random generator with an initial state that is
+ * unlikely to be duplicated by a subsequent instantiation.
+ *
+ * <p>The initial state (that is, the seed) is <i>partially</i> based
+ * on the current time of day in milliseconds.</p>
*
* @see #setSeed
*/
public Random() {
- setSeed(System.currentTimeMillis() + hashCode());
+ // Note: Using identityHashCode() to be hermetic wrt subclasses.
+ internalSetSeed(
+ System.currentTimeMillis() + System.identityHashCode(this));
}
+ // END android-changed
/**
* Construct a random generator with the given {@code seed} as the
@@ -72,7 +79,9 @@
* @see #setSeed
*/
public Random(long seed) {
- setSeed(seed);
+ // BEGIN android-changed
+ internalSetSeed(seed);
+ // END android-changed
}
/**
@@ -236,6 +245,7 @@
return ((long) next(32) << 32) + next(32);
}
+ // BEGIN android-changed
/**
* Modifies the seed a using linear congruential formula presented in <i>The
* Art of Computer Programming, Volume 2</i>, Section 3.2.1.
@@ -247,7 +257,20 @@
* @see #Random(long)
*/
public synchronized void setSeed(long seed) {
+ internalSetSeed(seed);
+ }
+
+ /**
+ * Sets the seed. This is used both in the constructor and in the
+ * default implementation of {@link #setSeed}.
+ *
+ * @param seed
+ * the seed that alters the state of the random number
+ * generator.
+ */
+ private void internalSetSeed(long seed) {
this.seed = (seed ^ multiplier) & ((1L << 48) - 1);
haveNextNextGaussian = false;
}
+ // END android-changed
}
diff --git a/luni/src/main/java/java/util/Scanner.java b/luni/src/main/java/java/util/Scanner.java
index dd5c024..f1ca423 100644
--- a/luni/src/main/java/java/util/Scanner.java
+++ b/luni/src/main/java/java/util/Scanner.java
@@ -1039,7 +1039,7 @@
* Returns the next token if it matches the specified pattern. The token
* will be both prefixed and postfixed by the delimiter that is currently
* being used (or a string that matches the delimiter pattern). This method will block
- * if input is being read. Calling this methos is equivalent to
+ * if input is being read. Calling this method is equivalent to
* {@code next(Pattern.compile(pattern))}.
*
* @param pattern
@@ -1638,7 +1638,7 @@
* Returns a string representation of this {@code Scanner}. The information
* returned may be helpful for debugging. The format of the string is unspecified.
*
- * @return a string represendation of this {@code Scanner}.
+ * @return a string representation of this {@code Scanner}.
*/
@Override
public String toString() {
diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java
index b4878ca..09dcae2 100644
--- a/luni/src/main/java/java/util/TimeZone.java
+++ b/luni/src/main/java/java/util/TimeZone.java
@@ -149,7 +149,7 @@
TimeZone zone = (TimeZone) super.clone();
return zone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/TreeMap.java b/luni/src/main/java/java/util/TreeMap.java
index b97821f..67b39e8 100644
--- a/luni/src/main/java/java/util/TreeMap.java
+++ b/luni/src/main/java/java/util/TreeMap.java
@@ -61,7 +61,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
@@ -1065,7 +1065,7 @@
}
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/TreeSet.java b/luni/src/main/java/java/util/TreeSet.java
index 375b9c8..fcd6224 100644
--- a/luni/src/main/java/java/util/TreeSet.java
+++ b/luni/src/main/java/java/util/TreeSet.java
@@ -160,7 +160,7 @@
}
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/java/util/UnknownFormatFlagsException.java b/luni/src/main/java/java/util/UnknownFormatFlagsException.java
index 2a1b075..66d9076 100644
--- a/luni/src/main/java/java/util/UnknownFormatFlagsException.java
+++ b/luni/src/main/java/java/util/UnknownFormatFlagsException.java
@@ -60,6 +60,7 @@
*/
@Override
public String getMessage() {
- return Msg.getString("K034a", flags);
+ // K034a=The flags are {0}
+ return Msg.getString("K034a", flags); //$NON-NLS-1$
}
}
diff --git a/luni/src/main/java/java/util/Vector.java b/luni/src/main/java/java/util/Vector.java
index 6a4060a..9a1b81c 100644
--- a/luni/src/main/java/java/util/Vector.java
+++ b/luni/src/main/java/java/util/Vector.java
@@ -265,7 +265,7 @@
vector.elementData = elementData.clone();
return vector;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/io/FileCanonPathCache.java b/luni/src/main/java/org/apache/harmony/luni/internal/io/FileCanonPathCache.java
deleted file mode 100644
index e3ea7b5..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/io/FileCanonPathCache.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.io;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-
-/**
- * A simple cache implementation for file's canonical path. The cache has fixed
- * size <code> CACHE_SIZE </code> and cached elements would be expired. If
- * <code>put<code> method is invoked when cache is full, the oldest element will be removed.
- *
- */
-public class FileCanonPathCache {
-
- static private class CacheElement {
- String canonicalPath;
-
- long timestamp;
-
- public CacheElement(String path) {
- this.canonicalPath = path;
- this.timestamp = System.currentTimeMillis();
- }
- }
-
- /**
- * Max elemnts could be hold in the cache.
- */
- public static final int CACHE_SIZE = 256;
-
- private static HashMap<String, CacheElement> cache = new HashMap<String, CacheElement>(
- CACHE_SIZE);
-
- /**
- * FIFO queue for tracking age of elements.
- */
- private static LinkedList<String> list = new LinkedList<String>();
-
- private static Object lock = new Object();
-
- /**
- * Expired time.
- */
- private static long timeout = 600000;
-
- /**
- * Retrieve element from cache.
- *
- * @param path
- * absolute path.
- * @return canonical path of <code>path</code> if it's in cache.
- *
- */
- public static String get(String path) {
- CacheElement element = null;
- synchronized (lock) {
- element = cache.get(path);
- }
-
- if (element == null) {
- return null;
- }
-
- long time = System.currentTimeMillis();
- if (time - element.timestamp > timeout) {
- // remove all elements older than this one
- synchronized (lock) {
- if (cache.get(path) != null) {
- String oldest = null;
- do {
- oldest = list.removeFirst();
- cache.remove(path);
- } while (!path.equals(oldest));
- }
- }
- return null;
- }
-
- return element.canonicalPath;
- }
-
- /**
- * Put element to cache.
- *
- * @param path
- * absolute path.
- * @param canonicalPath
- * the canonical path of <code>path</code>.
- */
- public static void put(String path, String canonicalPath) {
- CacheElement element = new CacheElement(canonicalPath);
- synchronized (lock) {
- if (cache.size() >= CACHE_SIZE) {
- // cache is full
- String oldest = list.removeFirst();
- cache.remove(oldest);
- }
- cache.put(path, element);
- list.addLast(path);
- }
- }
-
- /**
- * Remove all elements from cache.
- */
- public static void clear() {
- synchronized (lock) {
- cache.clear();
- list.clear();
- }
- }
-
- public static long getTimeout() {
- return timeout;
- }
-
- public static void setTimeout(long timeout) {
- FileCanonPathCache.timeout = timeout;
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Handler.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Handler.java
index 25d1e69..94719fe 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Handler.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Handler.java
@@ -44,7 +44,7 @@
*/
@Override
protected URLConnection openConnection(URL u) throws IOException {
- return new HttpURLConnection(u, getDefaultPort());
+ return new HttpURLConnectionImpl(u, getDefaultPort());
}
/**
@@ -72,7 +72,7 @@
if (null == u || null == proxy) {
throw new IllegalArgumentException(Msg.getString("K034b")); //$NON-NLS-1$
}
- return new HttpURLConnection(u, getDefaultPort(), proxy);
+ return new HttpURLConnectionImpl(u, getDefaultPort(), proxy);
}
/**
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
index 24be092..bdd1d0a 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
@@ -88,7 +88,7 @@
}
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java
similarity index 97%
rename from luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
rename to luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java
index 2dea92b..1ba7d8c 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java
@@ -25,6 +25,7 @@
import java.net.Authenticator;
import java.net.CacheRequest;
import java.net.CacheResponse;
+import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
@@ -58,7 +59,7 @@
* such as connecting, sending request and getting the content from the remote
* server.
*/
-public class HttpURLConnection extends java.net.HttpURLConnection {
+public class HttpURLConnectionImpl extends HttpURLConnection {
private static final String POST = "POST"; //$NON-NLS-1$
private static final String GET = "GET"; //$NON-NLS-1$
@@ -280,13 +281,14 @@
@Override
public int read(byte[] buf, int offset, int length) throws IOException {
- if (buf == null) {
- throw new NullPointerException();
+ // Force buf null check first, and avoid int overflow
+ if (offset < 0 || offset > buf.length) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // avoid int overflow
- if (offset < 0 || length < 0 || offset > buf.length
- || buf.length - offset < length) {
- throw new ArrayIndexOutOfBoundsException();
+ if (length < 0 || buf.length - offset < length) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
if (bytesRemaining <= 0) {
disconnect(false);
@@ -421,13 +423,14 @@
@Override
public int read(byte[] buf, int offset, int length) throws IOException {
- if (buf == null) {
- throw new NullPointerException();
+ // Force buf null check first, and avoid int overflow
+ if (offset > buf.length || offset < 0) {
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
}
- // avoid int overflow
- if (offset < 0 || length < 0 || offset > buf.length
- || buf.length - offset < length) {
- throw new ArrayIndexOutOfBoundsException();
+ if (length < 0 || buf.length - offset < length) {
+ // K0031=Length out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
}
if (bytesRemaining <= 0) {
readChunkSize();
@@ -690,7 +693,7 @@
* @param url
* URL The URL this connection is connecting
*/
- protected HttpURLConnection(URL url) {
+ protected HttpURLConnectionImpl(URL url) {
this(url, 80);
}
@@ -702,7 +705,7 @@
* @param port
* int The default connection port
*/
- protected HttpURLConnection(URL url, int port) {
+ protected HttpURLConnectionImpl(URL url, int port) {
super(url);
defaultPort = port;
reqHeader = (Header) defaultReqHeader.clone();
@@ -730,7 +733,7 @@
* @param proxy
* Proxy The proxy which is used to make the connection
*/
- protected HttpURLConnection(URL url, int port, Proxy proxy) {
+ protected HttpURLConnectionImpl(URL url, int port, Proxy proxy) {
this(url, port);
this.proxy = proxy;
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/Handler.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/Handler.java
index ef68a71..c6bf994 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/Handler.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/Handler.java
@@ -32,7 +32,7 @@
@Override
protected URLConnection openConnection(URL url) throws IOException {
- return new HttpsURLConnection(url, getDefaultPort());
+ return new HttpsURLConnectionImpl(url, getDefaultPort());
}
@Override
@@ -42,7 +42,7 @@
// K034b=url and proxy can not be null
throw new IllegalArgumentException(Msg.getString("K034b")); //$NON-NLS-1$
}
- return new HttpsURLConnection(url, getDefaultPort(), proxy);
+ return new HttpsURLConnectionImpl(url, getDefaultPort(), proxy);
}
@Override
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java
similarity index 96%
rename from luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnection.java
rename to luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java
index 4d0aff7..2ad5b13 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java
@@ -28,16 +28,17 @@
import java.util.List;
import java.util.Map;
+import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocket;
-import org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection;
+import org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl;
import org.apache.harmony.luni.internal.nls.Messages;
/**
* HttpsURLConnection implementation.
*/
-public class HttpsURLConnection extends javax.net.ssl.HttpsURLConnection {
+public class HttpsURLConnectionImpl extends HttpsURLConnection {
// Https engine to be wrapped
private final HttpsEngine httpsEngine;
@@ -45,12 +46,12 @@
// SSLSocket to be used for connection
private SSLSocket sslSocket;
- protected HttpsURLConnection(URL url, int port) {
+ protected HttpsURLConnectionImpl(URL url, int port) {
super(url);
httpsEngine = new HttpsEngine(url, port);
}
- protected HttpsURLConnection(URL url, int port, Proxy proxy) {
+ protected HttpsURLConnectionImpl(URL url, int port, Proxy proxy) {
super(url);
httpsEngine = new HttpsEngine(url, port, proxy);
}
@@ -345,7 +346,7 @@
/**
* HttpsEngine
*/
- private class HttpsEngine extends HttpURLConnection {
+ private class HttpsEngine extends HttpURLConnectionImpl {
// In case of using proxy this field indicates
// if it is a SSL Tunnel establishing stage
@@ -364,7 +365,7 @@
if (connected) {
return;
}
- if (usingProxy() && !makingSSLTunnel) {
+ if (super.usingProxy() && !makingSSLTunnel) {
// SSL Tunnel through the proxy was not established yet, do so
makingSSLTunnel = true;
// first - make the connection
@@ -402,7 +403,7 @@
@Override
protected String requestString() {
- if (usingProxy()) {
+ if (super.usingProxy()) {
if (makingSSLTunnel) {
// we are making the SSL Tunneling, return remotehost:port
int port = url.getPort();
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java
index 4db9910..b31cb39 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java
@@ -42,7 +42,7 @@
*/
@Override
protected URLConnection openConnection(URL u) throws IOException {
- return new JarURLConnection(u);
+ return new JarURLConnectionImpl(u);
}
/**
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java
similarity index 70%
rename from luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java
rename to luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java
index 34e7d07..493b768 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java
@@ -25,6 +25,7 @@
import java.io.InputStream;
import java.net.ContentHandler;
import java.net.ContentHandlerFactory;
+import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
@@ -42,13 +43,13 @@
import org.apache.harmony.luni.util.Util;
/**
- * This subclass extends <code>URLConnection</code>.
+ * This subclass extends {@code URLConnection}.
* <p>
*
* This class is responsible for connecting and retrieving resources from a Jar
- * file which can be anywhere that can be refered to by an URL.
+ * file which can be anywhere that can be referred to by an URL.
*/
-public class JarURLConnection extends java.net.JarURLConnection {
+public class JarURLConnectionImpl extends JarURLConnection {
static HashMap<URL, JarFile> jarCache = new HashMap<URL, JarFile>();
@@ -62,14 +63,16 @@
private boolean closed;
-
/**
* @param url
* the URL of the JAR
* @throws MalformedURLException
* if the URL is malformed
+ * @throws IOException
+ * if there is a problem opening the connection.
*/
- public JarURLConnection(java.net.URL url) throws MalformedURLException, IOException {
+ public JarURLConnectionImpl(URL url) throws MalformedURLException,
+ IOException {
super(url);
jarFileURL = getJarFileURL();
jarFileURLConnection = jarFileURL.openConnection();
@@ -88,8 +91,8 @@
}
/**
- * Returns the Jar file refered by this <code>URLConnection</code>
- *
+ * Returns the Jar file referred by this {@code URLConnection}.
+ *
* @return the JAR file referenced by this connection
*
* @throws IOException
@@ -103,30 +106,30 @@
}
/**
- * Returns the Jar file refered by this <code>URLConnection</code>
- *
+ * Returns the Jar file referred by this {@code URLConnection}
+ *
* @throws IOException
* if an IO error occurs while connecting to the resource.
*/
private void findJarFile() throws IOException {
JarFile jar = null;
if (getUseCaches()) {
- synchronized(jarCache){
+ synchronized (jarCache) {
jarFile = jarCache.get(jarFileURL);
}
if (jarFile == null) {
jar = openJarFile();
- synchronized(jarCache){
+ synchronized (jarCache) {
jarFile = jarCache.get(jarFileURL);
- if (jarFile == null){
+ if (jarFile == null) {
jarCache.put(jarFileURL, jar);
jarFile = jar;
- }else{
+ } else {
jar.close();
}
}
}
- }else{
+ } else {
jarFile = openJarFile();
}
@@ -135,38 +138,42 @@
}
}
+ @SuppressWarnings("nls")
JarFile openJarFile() throws IOException {
JarFile jar = null;
- if (jarFileURL.getProtocol().equals("file")) { //$NON-NLS-1$
+ if (jarFileURL.getProtocol().equals("file")) {
jar = new JarFile(new File(Util.decode(jarFileURL.getFile(), false,
"UTF-8")), true, ZipFile.OPEN_READ);
} else {
final InputStream is = jarFileURL.openConnection().getInputStream();
try {
jar = AccessController
- .doPrivileged(new PrivilegedAction<JarFile>() {
- public JarFile run() {
- try {
- File tempJar = File.createTempFile("hyjar_", //$NON-NLS-1$
- ".tmp", null); //$NON-NLS-1$
- tempJar.deleteOnExit();
- FileOutputStream fos = new FileOutputStream(
- tempJar);
- byte[] buf = new byte[4096];
- int nbytes = 0;
- while ((nbytes = is.read(buf)) > -1) {
- fos.write(buf, 0, nbytes);
+ .doPrivileged(new PrivilegedAction<JarFile>() {
+ public JarFile run() {
+ try {
+ File tempJar = File.createTempFile(
+ "hyjar_", ".tmp", null);
+ tempJar.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(
+ tempJar);
+ byte[] buf = new byte[4096];
+ int nbytes = 0;
+ while ((nbytes = is.read(buf)) > -1) {
+ fos.write(buf, 0, nbytes);
+ }
+ fos.close();
+ return new JarFile(tempJar, true,
+ ZipFile.OPEN_READ
+ | ZipFile.OPEN_DELETE);
+ } catch (IOException e) {
+ return null;
}
- fos.close();
- return new JarFile(tempJar,
- true, ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
- } catch (IOException e) {
- return null;
}
- }
- });
+ });
} finally {
- if (is != null) is.close();
+ if (is != null) {
+ is.close();
+ }
}
}
@@ -174,11 +181,11 @@
}
/**
- * Returns the JarEntry of the entry referenced by this
- * <code>URLConnection</code>.
- *
- * @return java.util.jar.JarEntry the JarEntry referenced
- *
+ * Returns the JarEntry of the entry referenced by this {@code
+ * URLConnection}.
+ *
+ * @return the JarEntry referenced
+ *
* @throws IOException
* if an IO error occurs while getting the entry
*/
@@ -190,8 +197,8 @@
}
/**
- * Look up the JarEntry of the entry referenced by this
- * <code>URLConnection</code>.
+ * Look up the JarEntry of the entry referenced by this {@code
+ * URLConnection}.
*/
private void findJarEntry() throws IOException {
if (getEntryName() == null) {
@@ -213,15 +220,16 @@
*/
@Override
public InputStream getInputStream() throws IOException {
-
if (closed) {
- throw new IllegalStateException(Msg.getString("KA027"));
+ // KA027=Inputstream of the JarURLConnection has been closed
+ throw new IllegalStateException(Msg.getString("KA027")); //$NON-NLS-1$
}
connect();
if (jarInput != null) {
return jarInput;
}
if (jarEntry == null) {
+ // K00fc=Jar entry not specified
throw new IOException(Msg.getString("K00fc")); //$NON-NLS-1$
}
return jarInput = new JarURLConnectionInputStream(jarFile
@@ -229,11 +237,11 @@
}
/**
- * Returns the content type of the resource.
- * For jar file itself "x-java/jar" should be returned,
- * for jar entries the content type of the entry should be returned.
- * Returns non-null results ("content/unknown" for unknown types).
- *
+ * Returns the content type of the resource. For jar file itself
+ * "x-java/jar" should be returned, for jar entries the content type of the
+ * entry should be returned. Returns non-null results ("content/unknown" for
+ * unknown types).
+ *
* @return the content type
*/
@Override
@@ -241,31 +249,30 @@
if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
// the type for jar file itself is always "x-java/jar"
return "x-java/jar"; //$NON-NLS-1$
- } else {
- String cType = null;
- String entryName = getEntryName();
-
- if (entryName != null) {
- // if there is an Jar Entry, get the content type from the name
- cType = guessContentTypeFromName(entryName);
- } else {
- try {
- connect();
- cType = jarFileURLConnection.getContentType();
- } catch (IOException ioe) {
- // Ignore
- }
- }
- if (cType == null) {
- cType = "content/unknown"; //$NON-NLS-1$
- }
- return cType;
}
+ String cType = null;
+ String entryName = getEntryName();
+
+ if (entryName != null) {
+ // if there is an Jar Entry, get the content type from the name
+ cType = guessContentTypeFromName(entryName);
+ } else {
+ try {
+ connect();
+ cType = jarFileURLConnection.getContentType();
+ } catch (IOException ioe) {
+ // Ignore
+ }
+ }
+ if (cType == null) {
+ cType = "content/unknown"; //$NON-NLS-1$
+ }
+ return cType;
}
/**
* Returns the content length of the resource. Test cases reveal that if the
- * URL is refering to a Jar file, this method returns a content-length
+ * URL is referring to a Jar file, this method answers a content-length
* returned by URLConnection. For jar entry it should return it's size.
* Otherwise, it will return -1.
*
@@ -277,26 +284,25 @@
connect();
if (jarEntry == null) {
return jarFileURLConnection.getContentLength();
- } else {
- return (int) getJarEntry().getSize();
}
+ return (int) getJarEntry().getSize();
} catch (IOException e) {
- //Ignored
+ // Ignored
}
return -1;
}
/**
- * Returns the object pointed by this <code>URL</code>. If this
- * URLConnection is pointing to a Jar File (no Jar Entry), this method will
- * return a <code>JarFile</code> If there is a Jar Entry, it will return
- * the object corresponding to the Jar entry content type.
- *
+ * Returns the object pointed by this {@code URL}. If this URLConnection is
+ * pointing to a Jar File (no Jar Entry), this method will return a {@code
+ * JarFile} If there is a Jar Entry, it will return the object corresponding
+ * to the Jar entry content type.
+ *
* @return a non-null object
*
* @throws IOException
- * if an IO error occured
- *
+ * if an IO error occurred
+ *
* @see ContentHandler
* @see ContentHandlerFactory
* @see java.io.IOException
@@ -354,9 +360,9 @@
*/
public static void closeCachedFiles() {
Set<Map.Entry<URL, JarFile>> s = jarCache.entrySet();
- synchronized(jarCache){
+ synchronized (jarCache) {
Iterator<Map.Entry<URL, JarFile>> i = s.iterator();
- while(i.hasNext()){
+ while (i.hasNext()) {
try {
ZipFile zip = i.next().getValue();
if (zip != null) {
@@ -366,7 +372,7 @@
// Ignored
}
}
- }
+ }
}
private class JarURLConnectionInputStream extends FilterInputStream {
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfo.java b/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfo.java
index 110a0fd..01319e1 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfo.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfo.java
@@ -111,12 +111,23 @@
// Subtract the raw offset from all offsets so it can be changed
// and affect them too.
- // Find whether there exist any observances of DST.
-
for (int i = 0; i < mGmtOffs.length; i++) {
mGmtOffs[i] -= mRawOffset;
+ }
- if (mIsDsts[i] != 0) {
+ // Is this zone still observing DST?
+ // We don't care if they've historically used it: most places have at least once.
+ // We want to know whether the last "schedule info" (the unix times in the mTransitions
+ // array) is in the future. If it is, DST is still relevant.
+ // See http://code.google.com/p/android/issues/detail?id=877.
+ // This test means that for somewhere like Morocco, which tried DST in 2009 but has
+ // no future plans (and thus no future schedule info) will report "true" from
+ // useDaylightTime at the start of 2009 but "false" at the end. This seems appropriate.
+ long currentUnixTime = System.currentTimeMillis() / 1000;
+ if (mTransitions.length > 0) {
+ // (We're really dealing with uint32_t values, so long is most convenient in Java.)
+ long latestScheduleTime = mTransitions[mTransitions.length - 1] & 0xffffffff;
+ if (currentUnixTime < latestScheduleTime) {
mUseDst = true;
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
index ac0c877..cbecab5 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
@@ -154,7 +154,6 @@
close();
}
- @Override
public Object getOption(int optID) throws SocketException {
if (optID == SocketOptions.SO_TIMEOUT) {
return Integer.valueOf(receiveTimeout);
@@ -285,7 +284,6 @@
* @throws SocketException thrown if the option value is unsupported or
* invalid
*/
- @Override
public void setOption(int optID, Object val) throws SocketException {
/*
* for datagram sockets on some platforms we have to set both the
@@ -344,7 +342,9 @@
@Override
public void setTimeToLive(int ttl) throws java.io.IOException {
- setOption(IP_MULTICAST_TTL, Byte.valueOf((byte) (ttl & 0xFF)));
+ // BEGIN android-changed: native code wants an int anyway
+ setOption(IP_MULTICAST_TTL, Integer.valueOf(ttl));
+ // END android-changed
if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
this.ttl = ttl;
}
@@ -352,10 +352,9 @@
@Override
public void setTTL(byte ttl) throws java.io.IOException {
- setOption(IP_MULTICAST_TTL, Byte.valueOf(ttl));
- if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
- this.ttl = ttl;
- }
+ // BEGIN android-changed: remove duplication
+ setTimeToLive(ttl);
+ // END android-changed
}
@Override
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
index 9a3ae6e..6773fd4 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
@@ -560,10 +560,7 @@
if (shutdownInput) {
return -1;
}
- // BEGIN android-changed
- // call receiveStream() instead of read()
- int read = netImpl.receiveStream(fd, buffer, offset, count, receiveTimeout);
- // END android-changed
+ int read = netImpl.read(fd, buffer, offset, count, receiveTimeout);
// Return of zero bytes for a blocking socket means a timeout occurred
if (read == 0) {
throw new SocketTimeoutException();
@@ -580,9 +577,6 @@
return netImpl.sendDatagram2(fd, buffer, offset, count, port,
address);
}
- // BEGIN android-changed
- // call sendStream() instead of write()
- return netImpl.sendStream(fd, buffer, offset, count);
- // END android-changed
+ return netImpl.write(fd, buffer, offset, count);
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/SocketInputStream.java b/luni/src/main/java/org/apache/harmony/luni/net/SocketInputStream.java
index 4b0b4b4..d19206d 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/SocketInputStream.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/SocketInputStream.java
@@ -78,7 +78,8 @@
}
if (0 > offset || offset >= buffer.length) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e"));//$NON-NLS-1$
+ // K002e=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset));//$NON-NLS-1$
}
if (0 > count || offset + count > buffer.length) {
throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f"));//$NON-NLS-1$
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/FileDescriptorHandler.java b/luni/src/main/java/org/apache/harmony/luni/platform/FileDescriptorHandler.java
index 94dbba3..9afee7e 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/FileDescriptorHandler.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/FileDescriptorHandler.java
@@ -20,14 +20,14 @@
import java.io.FileDescriptor;
/**
- * This interface declares method to get wrapped <code>FileDescritpor</code>.
+ * This interface declares method to get wrapped <code>FileDescriptor</code>.
*/
public interface FileDescriptorHandler {
/**
- * Get the wrapped <code>FileDescritpor</code>.
+ * Get the wrapped <code>FileDescriptor</code>.
*
- * @return the wrapped <code>FileDescritpor</code>.
+ * @return the wrapped <code>FileDescriptor</code>.
*/
FileDescriptor getFD();
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
index 7613f0e..bee1557 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
@@ -108,10 +108,9 @@
// BEGIN android-deleted
// public long ttyAvailable() throws IOException;
+ // public long ttyRead(byte[] bytes, int offset, int length) throws IOException;
// END android-deleted
- public long ttyRead(byte[] bytes, int offset, int length) throws IOException;
-
// BEGIN android-added
public int ioctlAvailable(int fileDescriptor) throws IOException;
// END android-added
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java
index 6e8028a..f7a0209 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java
@@ -515,7 +515,7 @@
*
* @param fileDescriptor
* a handle to the file that is to be memory mapped.
- * @param alignment
+ * @param offset
* the offset in the file where the mapping should begin.
* @param size
* the number of bytes that are requested to map.
@@ -528,8 +528,10 @@
* @throws IOException
* if an exception occurs mapping the file into memory.
*/
- public int mmap(int fileDescriptor, long alignment, long size, int mapMode)
+ // BEGIN android-changed: rename 'alignment' to 'offset'.
+ public int mmap(int fileDescriptor, long offset, long size, int mapMode)
throws IOException;
+ // END android-changed
/**
* TODO: JavaDoc
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
index fb47f0d..71a272a 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
@@ -57,7 +57,7 @@
public int read(FileDescriptor aFD, byte[] data, int offset, int count,
int timeout) throws IOException;
- public int readDirect(FileDescriptor aFD, int address, int offset, int count,
+ public int readDirect(FileDescriptor aFD, int address, int count,
int timeout) throws IOException;
public int write(FileDescriptor fd, byte[] data, int offset, int count)
@@ -66,11 +66,18 @@
public int writeDirect(FileDescriptor fd, int address, int offset, int count)
throws IOException;
+ // BEGIN android-removed
+ // public int writev(FileDescriptor fd, Object[] buffers, int[] offsets,
+ // int[] counts, int length) throws IOException;
+ // END android-removed
+
public void setNonBlocking(FileDescriptor aFD, boolean block)
throws IOException;
- public int connect(FileDescriptor aFD, int trafficClass,
+ // BEGIN android-changed (we always throw on error, the value returned was always 0)
+ public void connect(FileDescriptor aFD, int trafficClass,
InetAddress inetAddress, int port) throws IOException;
+ // END android-changed
// BEGIN android-changed
public int connectWithTimeout(FileDescriptor aFD, int timeout,
@@ -119,18 +126,6 @@
public void connectDatagram(FileDescriptor aFD, int port, int trafficClass,
InetAddress inetAddress) throws SocketException;
- /**
- * @deprecated Use {@link #read(FileDescriptor, byte[], int, int, int)}
- */
- @Deprecated
- public int receiveStream(FileDescriptor aFD, byte[] data, int offset,
- int count, int timeout) throws IOException;
-
- // BEGIN android-added
- public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
- throws IOException;
- // END android-added
-
public void shutdownInput(FileDescriptor descriptor) throws IOException;
public void shutdownOutput(FileDescriptor descriptor) throws IOException;
@@ -166,9 +161,42 @@
public InetAddress getSocketLocalAddress(FileDescriptor aFD,
boolean preferIPv6Addresses);
- public int[] select(FileDescriptor[] readFDs,
- FileDescriptor[] writeFDs, long timeout)
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ /**
+ * Select the given file descriptors for read and write operations.
+ *
+ * <p>The first {@code numReadable} file descriptors of {@code readFDs} will
+ * be selected for read-ready operations. The first {@code numWritable} file
+ * descriptors in {@code writeFDs} will be selected for write-ready
+ * operations. A file descriptor can appear in either or both and must not
+ * be null. If the file descriptor is closed during the select the behavior
+ * depends upon the underlying OS.
+ *
+ * @param readFDs
+ * all sockets interested in read and accept
+ * @param writeFDs
+ * all sockets interested in write and connect
+ * @param numReadable
+ * the size of the subset of readFDs to read or accept.
+ * @param numWritable
+ * the size of the subset of writeFDs to write or connect
+ * @param timeout
+ * timeout in milliseconds
+ * @param flags
+ * for output. Length must be at least {@code numReadable
+ * + numWritable}. Upon returning, each element describes the
+ * state of the descriptor in the corresponding read or write
+ * array. See {@code SelectorImpl.READABLE} and {@code
+ * SelectorImpl.WRITEABLE}
+ * @return true
+ * unless selection timed out or was interrupted
+ * @throws SocketException
+ */
+ public boolean select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
+ int numReadable, int numWritable, long timeout, int[] flags)
throws SocketException;
+ // END android-changed
/*
* Query the IP stack for the local port to which this socket is bound.
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
index 08bdac6..b7a62e2 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
@@ -69,7 +69,7 @@
* Note that this value for Windows differs from the one for the
* page size (64K and 4K respectively).
*/
- public native int getAllocGranularity() throws IOException;
+ public native int getAllocGranularity();
public boolean lock(int fileDescriptor, long start, long length, int type,
boolean waitFlag) throws IOException {
@@ -79,160 +79,71 @@
return result != -1;
}
- private native int unlockImpl(int fileDescriptor, long start, long length);
+ // BEGIN android-changed
+ private native void unlockImpl(int fileDescriptor, long start, long length) throws IOException;
public void unlock(int fileDescriptor, long start, long length)
throws IOException {
// Validate arguments
validateLockArgs(IFileSystem.SHARED_LOCK_TYPE, start, length);
- int result = unlockImpl(fileDescriptor, start, length);
- if (result == -1) {
- throw new IOException();
- }
+ unlockImpl(fileDescriptor, start, length);
}
- private native int fflushImpl(int fd, boolean metadata);
-
- public void fflush(int fileDescriptor, boolean metadata)
- throws IOException {
- int result = fflushImpl(fileDescriptor, metadata);
- if (result == -1) {
- throw new IOException();
- }
- }
+ public native void fflush(int fileDescriptor, boolean metadata) throws IOException;
/*
* File position seeking.
*/
-
- private native long seekImpl(int fd, long offset, int whence);
-
- public long seek(int fileDescriptor, long offset, int whence)
- throws IOException {
- long pos = seekImpl(fileDescriptor, offset, whence);
- if (pos == -1) {
- throw new IOException();
- }
- return pos;
- }
+ public native long seek(int fd, long offset, int whence) throws IOException;
/*
* Direct read/write APIs work on addresses.
*/
- private native long readDirectImpl(int fileDescriptor, int address,
- int offset, int length);
+ public native long readDirect(int fileDescriptor, int address, int offset, int length);
- public long readDirect(int fileDescriptor, int address, int offset,
- int length) throws IOException {
- long bytesRead = readDirectImpl(fileDescriptor, address, offset, length);
- if (bytesRead < -1) {
- throw new IOException();
- }
- return bytesRead;
- }
-
- private native long writeDirectImpl(int fileDescriptor, int address,
- int offset, int length);
-
- public long writeDirect(int fileDescriptor, int address, int offset,
- int length) throws IOException {
- long bytesWritten = writeDirectImpl(fileDescriptor, address, offset,
- length);
- if (bytesWritten < 0) {
- throw new IOException();
- }
- return bytesWritten;
- }
+ public native long writeDirect(int fileDescriptor, int address, int offset, int length)
+ throws IOException;
/*
* Indirect read/writes work on byte[]'s
*/
private native long readImpl(int fileDescriptor, byte[] bytes, int offset,
- int length);
+ int length) throws IOException;
public long read(int fileDescriptor, byte[] bytes, int offset, int length)
throws IOException {
if (bytes == null) {
throw new NullPointerException();
}
- long bytesRead = readImpl(fileDescriptor, bytes, offset, length);
- if (bytesRead < -1) {
- /*
- * TODO: bytesRead is never less than -1 so this code
- * does nothing?
- * The native code throws an exception in only one case
- * so perhaps this should be 'bytesRead < 0' to handle
- * any other cases. But the other cases have been
- * ignored until now so fixing this could break things
- */
- throw new IOException();
- }
- return bytesRead;
+ return readImpl(fileDescriptor, bytes, offset, length);
}
private native long writeImpl(int fileDescriptor, byte[] bytes,
- int offset, int length);
+ int offset, int length) throws IOException;
public long write(int fileDescriptor, byte[] bytes, int offset, int length)
throws IOException {
- long bytesWritten = writeImpl(fileDescriptor, bytes, offset, length);
- if (bytesWritten < 0) {
- throw new IOException();
+ if (bytes == null) {
+ throw new NullPointerException();
}
- return bytesWritten;
+ return writeImpl(fileDescriptor, bytes, offset, length);
}
+ // END android-changed
/*
* Scatter/gather calls.
*/
- public long readv(int fileDescriptor, int[] addresses, int[] offsets,
- int[] lengths, int size) throws IOException {
- long bytesRead = readvImpl(fileDescriptor, addresses, offsets, lengths,
- size);
- if (bytesRead < -1) {
- throw new IOException();
- }
- return bytesRead;
- }
+ public native long readv(int fileDescriptor, int[] addresses,
+ int[] offsets, int[] lengths, int size) throws IOException;
- private native long readvImpl(int fileDescriptor, int[] addresses,
- int[] offsets, int[] lengths, int size);
+ public native long writev(int fileDescriptor, int[] addresses, int[] offsets,
+ int[] lengths, int size) throws IOException;
- public long writev(int fileDescriptor, int[] addresses, int[] offsets,
- int[] lengths, int size) throws IOException {
- long bytesWritten = writevImpl(fileDescriptor, addresses, offsets,
- lengths, size);
- if (bytesWritten < 0) {
- throw new IOException();
- }
- return bytesWritten;
- }
+ // BEGIN android-changed
+ public native void close(int fileDescriptor) throws IOException;
- private native long writevImpl(int fileDescriptor, int[] addresses,
- int[] offsets, int[] lengths, int size);
-
- private native int closeImpl(int fileDescriptor);
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.harmony.luni.platform.IFileSystem#close(long)
- */
- public void close(int fileDescriptor) throws IOException {
- int rc = closeImpl(fileDescriptor);
- if (rc == -1) {
- throw new IOException();
- }
- }
-
- public void truncate(int fileDescriptor, long size) throws IOException {
- int rc = truncateImpl(fileDescriptor, size);
- if (rc < 0) {
- throw new IOException();
- }
- }
-
- private native int truncateImpl(int fileDescriptor, long size);
+ public native void truncate(int fileDescriptor, long size) throws IOException;
+ // END android-changed
public int open(byte[] fileName, int mode) throws FileNotFoundException {
if (fileName == null) {
@@ -254,16 +165,10 @@
private native int openImpl(byte[] fileName, int mode);
- public long transfer(int fileHandler, FileDescriptor socketDescriptor,
- long offset, long count) throws IOException {
- long result = transferImpl(fileHandler, socketDescriptor, offset, count);
- if (result < 0)
- throw new IOException();
- return result;
- }
-
- private native long transferImpl(int fileHandler,
- FileDescriptor socketDescriptor, long offset, long count);
+ // BEGIN android-changed
+ public native long transfer(int fd, FileDescriptor sd, long offset, long count)
+ throws IOException;
+ // END android-changed
// BEGIN android-deleted
// public long ttyAvailable() throws IOException {
@@ -277,17 +182,15 @@
// private native long ttyAvailableImpl();
// END android-deleted
- public long ttyRead(byte[] bytes, int offset, int length) throws IOException {
- long nChar = ttyReadImpl(bytes, offset, length);
- // BEGIN android-changed
- if (nChar < -1) {
- throw new IOException();
- }
- // END android-changed
- return nChar;
- }
-
- private native long ttyReadImpl(byte[] bytes, int offset, int length);
+ // BEGIN android-deleted
+ // public long ttyRead(byte[] bytes, int offset, int length) throws IOException {
+ // if (bytes == null) {
+ // throw new NullPointerException();
+ // }
+ // return ttyReadImpl(bytes, offset, length);
+ // }
+ // private native long ttyReadImpl(byte[] bytes, int offset, int length) throws IOException;
+ // END android-deleted
// BEGIN android-added
public native int ioctlAvailable(int fileDescriptor) throws IOException;
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java
index 0061d2a..b490da5 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java
@@ -73,29 +73,33 @@
return singleton;
}
- /**
- * This class is not designed to be publicly instantiated.
- *
- * @see #getOSMemory()
+ /*
+ * Native method to determine whether the underlying platform is little
+ * endian.
+ *
+ * @return <code>true</code> if the platform is little endian or
+ * <code>false</code> if it is big endian.
*/
- private OSMemory() {
- super();
- }
-
- /**
- * Returns whether the byte order of this machine is little endian or not..
- *
- * @return <code>false</code> for Big Endian, and
- * <code>true</code. for Little Endian.
- */
- // BEGIN android-changed
- /*public*/
private static native boolean isLittleEndianImpl();
- // END android-changed
- public boolean isLittleEndian() {
- return isLittleEndianImpl();
- }
+ /**
+ * This class is not designed to be publicly instantiated.
+ *
+ * @see #getOSMemory()
+ */
+ private OSMemory() {
+ super();
+ }
+
+ /**
+ * Returns whether the byte order of this machine is little endian or not.
+ *
+ * @return <code>false</code> for Big Endian, and
+ * <code>true</code> for Little Endian.
+ */
+ public boolean isLittleEndian() {
+ return NATIVE_ORDER == Endianness.LITTLE_ENDIAN;
+ }
/**
* Returns the natural byte order for this machine.
@@ -128,16 +132,8 @@
* @return the address of the start of the memory block.
* @throws OutOfMemoryError
* if the request cannot be satisfied.
- */
- // BEGIN android-changed
- // public long malloc(long length) throws OutOfMemoryError
- // {
- // OSResourcesMonitor.ensurePhysicalMemoryCapacity();
- // return mallocNative(length);
- // }
- // private native long mallocNative(long length) throws OutOfMemoryError;
+ */
public native int malloc(int length) throws OutOfMemoryError;
- // END android-changed
/**
* Deallocates space for a memory block that was previously allocated by a
@@ -612,20 +608,17 @@
*/
public native void setAddress(int address, int value);
- /*
- * Memory mapped file
- */
- private native int mmapImpl(int fileDescriptor, long alignment,
- long size, int mapMode);
+ // BEGIN android-changed: more error checking, rename 'alignment' to 'offset'.
+ private native int mmapImpl(int fd, long offset, long size, int mapMode);
- public int mmap(int fileDescriptor, long alignment, long size,
- int mapMode) throws IOException {
- int address = mmapImpl(fileDescriptor, alignment, size, mapMode);
- if (address == -1) {
- throw new IOException();
+ public int mmap(int fd, long offset, long size, int mapMode) throws IOException {
+ // Check just those errors mmap(2) won't detect.
+ if (offset < 0 || size < 0 || offset > Integer.MAX_VALUE || size > Integer.MAX_VALUE) {
+ throw new IllegalArgumentException("offset=" + offset + " size=" + size);
}
- return address;
+ return mmapImpl(fd, offset, size, mapMode);
}
+ // END android-changed
private native void unmapImpl(int addr, long size);
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
index bd6a6097..9901412 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
@@ -109,13 +109,12 @@
static native void socketBindImpl(FileDescriptor aFD, int port, InetAddress inetAddress) throws SocketException;
- public int connect(FileDescriptor fd, int trafficClass,
+ // BEGIN android-changed (removed unused return value and useless native method)
+ public void connect(FileDescriptor fd, int trafficClass,
InetAddress inetAddress, int port) throws IOException{
- return connectSocketImpl(fd, trafficClass, inetAddress, port);
+ connectStreamWithTimeoutSocketImpl(fd, port, 0, trafficClass, inetAddress);
}
-
- static native int connectSocketImpl(FileDescriptor aFD,
- int trafficClass, InetAddress inetAddress, int port);
+ // END android-changed
public void connectDatagram(FileDescriptor fd, int port,
int trafficClass, InetAddress inetAddress) throws SocketException {
@@ -290,11 +289,7 @@
static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
throws SocketException;
- public Channel inheritedChannel() {
- return inheritedChannelImpl();
- }
-
- native Channel inheritedChannelImpl();
+ public native Channel inheritedChannel();
// BEGIN android-removed
// public boolean isReachableByICMP(final InetAddress dest,
@@ -376,6 +371,12 @@
*/
public int read(FileDescriptor fd, byte[] data, int offset, int count,
int timeout) throws IOException {
+ // BEGIN android-added safety!
+ if (offset < 0 || count < 0 || offset > data.length - count) {
+ throw new IllegalArgumentException("data.length=" + data.length + " offset=" + offset +
+ " count=" + count);
+ }
+ // END android-added
return readSocketImpl(fd, data, offset, count, timeout);
}
@@ -400,12 +401,12 @@
* @throws IOException
* if an underlying socket exception occurred
*/
- public int readDirect(FileDescriptor fd, int address, int offset, int count,
+ public int readDirect(FileDescriptor fd, int address, int count,
int timeout) throws IOException {
- return readSocketDirectImpl(fd, address, offset, count, timeout);
+ return readSocketDirectImpl(fd, address, count, timeout);
}
- static native int readSocketDirectImpl(FileDescriptor aFD, int address, int offset, int count,
+ static native int readSocketDirectImpl(FileDescriptor aFD, int address, int count,
int timeout) throws IOException;
/**
@@ -454,56 +455,7 @@
int receiveTimeout, boolean peek) throws IOException;
/**
- * Receive at most <code>count</code> bytes into the buffer
- * <code>data</code> at the <code>offset</code> on the socket.
- *
- * @param aFD
- * the socket FileDescriptor
- * @param data
- * the receive buffer
- * @param offset
- * the offset into the buffer
- * @param count
- * the max number of bytes to receive
- * @param timeout
- * the max time the read operation should block waiting for data
- * @return the actual number of bytes read
- * @throws IOException
- * @throws SocketException
- * if an error occurs while reading
- * @deprecated use {@link #read(FileDescriptor, byte[], int, int, int)}
- */
- public int receiveStream(FileDescriptor aFD, byte[] data,
- int offset, int count, int timeout) throws IOException {
- return receiveStreamImpl(aFD, data, offset, count, timeout);
- }
-
- static native int receiveStreamImpl(FileDescriptor aFD, byte[] data,
- int offset, int count, int timeout) throws IOException;
-
- // BEGIN android-added
- /**
- * Send <code>count</code> bytes from the buffer <code>data</code> at
- * the <code>offset</code>, on the socket.
- *
- * @param fd
- *
- * @param data the send buffer @param offset the offset into the buffer
- * @param count the number of bytes to receive @return int the actual number
- * of bytes sent @throws IOException @exception SocketException if an error
- * occurs while writing
- */
- public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
- throws IOException {
- return sendStreamImpl(fd, data, offset, count);
- }
-
- static native int sendStreamImpl(FileDescriptor fd, byte[] data,
- int offset, int count) throws IOException;
- // END android-added
-
- /**
- * Recieve data on the connected socket into the specified buffer. The
+ * Receive data on the connected socket into the specified buffer. The
* packet fields <code>data</code> and <code>length</code> are passed in
* addition to <code>packet</code> to eliminate the JNI field access calls.
*
@@ -546,58 +498,33 @@
DatagramPacket packet, int address, int offset, int length,
int receiveTimeout, boolean peek) throws IOException;
- /**
- * Select the given file descriptors for read and write operations.
- *
- * The file descriptors passed in as readFDs will be selected for read-ready
- * operations, and those in the writeFDs will be selected for write-ready
- * operations. A file descriptor can appear in either or both array, and
- * must not be <code>null</code>. If the file descriptor is closed during
- * the select the behavior depends upon the underlying OS.
- *
- * Upon return the result is a single array of length
- * <code>readFDs.length</code> + <code>writeFDs.length</code> laid out as
- * the result of the select operation on the corresponding file descriptors.
- *
- * @param readFDs
- * all sockets interested in read and accept
- * @param writeFDs
- * all sockets interested in write and connect
- * @param timeout
- * timeout in milliseconds
- * @return each element describes the corresponding state of the descriptor
- * in the read and write arrays.
- * @throws SocketException
- */
- public int[] select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
- long timeout) throws SocketException {
- int countRead = readFDs.length;
- int countWrite = writeFDs.length;
- int result = 0;
- if (0 == countRead + countWrite) {
- return (new int[0]);
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ public boolean select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
+ int numReadable, int numWritable, long timeout, int[] flags)
+ throws SocketException {
+ if (numReadable < 0 || numWritable < 0) {
+ throw new IllegalArgumentException();
}
- int[] flags = new int[countRead + countWrite];
- assert validateFDs(readFDs, writeFDs) : "Invalid file descriptor arrays"; //$NON-NLS-1$
-
- // handle timeout in native
- result = selectImpl(readFDs, writeFDs, countRead, countWrite, flags,
- timeout);
-
- if (0 <= result) {
- return flags;
+ int total = numReadable + numWritable;
+ if (total == 0) {
+ return true;
}
- if (ERRORCODE_SOCKET_TIMEOUT == result ||
- ERRORCODE_SOCKET_INTERRUPTED == result) {
- return new int[0];
- }
- throw new SocketException();
+
+ assert validateFDs(readFDs, writeFDs, numReadable, numWritable) : "Invalid file descriptor arrays"; //$NON-NLS-1$
+
+ // BEGIN android-changed: handle errors in native code
+ return selectImpl(readFDs, writeFDs, numReadable, numWritable, flags, timeout);
+ // END android-changed
}
+ // END android-changed
- static native int selectImpl(FileDescriptor[] readfd,
+ // BEGIN android-changed: return type (we throw in native code, with descriptive errors)
+ static native boolean selectImpl(FileDescriptor[] readfd,
FileDescriptor[] writefd, int cread, int cwirte, int[] flags,
long timeout);
+ // END android-changed
/**
* Send the <code>data</code> to the address and port to which the was
@@ -781,6 +708,25 @@
return true;
}
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ private boolean validateFDs(FileDescriptor[] readFDs,
+ FileDescriptor[] writeFDs, int countRead, int countWrite) {
+ for (int i = 0; i < countRead; ++i) {
+ // Also checks fd not null
+ if (!readFDs[i].valid()) {
+ return false;
+ }
+ }
+ for (int i = 0; i < countWrite; ++i) {
+ if (!writeFDs[i].valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // END android-changed
+
/**
* Write bytes from a byte array to a socket.
*
@@ -829,4 +775,28 @@
static native int writeSocketDirectImpl(FileDescriptor fd, int address, int offset, int count)
throws IOException;
+
+ // BEGIN android-removed
+ // /**
+ // * Write given buffers to a socket. The given buffers is a Object array, the
+ // * element of array must be direct buffer or a byte array to be written.
+ // *
+ // * @param fd
+ // * the socket on which to write the bytes
+ // * @param buffers
+ // * the element of array must be direct buffer or a byte array to
+ // * be written
+ // * @param offsets
+ // * the index of the first byte to be write
+ // * @param counts
+ // * the maximum number of bytes to be written
+ // * @param length
+ // * the size of buffer array
+ // * @return the actual number of bytes written
+ // * @throws IOException
+ // * if there is an underlying socket problem
+ // */
+ // public native int writev(FileDescriptor fd, Object[] buffers,
+ // int[] offsets, int[] counts, int length) throws IOException;
+ // END android-removed
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddress.java b/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddress.java
index 43702b2..0149cac 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddress.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddress.java
@@ -21,14 +21,17 @@
package org.apache.harmony.luni.platform;
-
/**
* The platform address class is an unsafe virtualization of an OS memory block.
- *
*/
public class PlatformAddress implements ICommonDataTypes, Comparable {
/**
+ * This final field defines the sentinel for an unknown address value.
+ */
+ static final int UNKNOWN = -1;
+
+ /**
* This final field defines the size of an address on this platform.
*/
static final int SIZEOF = Platform.getMemorySystem().getPointerSize();
@@ -38,12 +41,17 @@
*/
public static final PlatformAddress NULL = new PlatformAddress(0, 0);
+ /**
+ * INVALID is the canonical address with an invalid value
+ * (i.e. a non-address).
+ */
+ public static final PlatformAddress INVALID =
+ new PlatformAddress(UNKNOWN, UNKNOWN);
+
public static final IMemorySpy memorySpy = new RuntimeMemorySpy();
static final IMemorySystem osMemory = Platform.getMemorySystem();
- static final long UNKNOWN = -1;
-
final int osaddr;
final long size;
@@ -65,7 +73,7 @@
memorySpy.autoFree(this);
}
- public PlatformAddress duplicate(){
+ public PlatformAddress duplicate() {
return PlatformAddressFactory.on(osaddr, size);
}
@@ -264,7 +272,7 @@
return "PlatformAddress[" + osaddr + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
- public final long getSize(){
+ public final long getSize() {
return size;
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddressFactory.java b/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddressFactory.java
index 9ac8064..3590604 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddressFactory.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddressFactory.java
@@ -103,7 +103,12 @@
return addr;
}
- public static PlatformAddress allocMap(int fd, long start, long size, int mode) throws IOException{
+ public static PlatformAddress allocMap(int fd, long start, long size, int mode) throws IOException {
+ if (size == 0) {
+ // if size is 0, call to mmap has incorrect behaviour on
+ // unix and windows, so return empty address
+ return mapOn(0, 0);
+ }
int osAddress = PlatformAddress.osMemory.mmap(fd, start, size, mode);
PlatformAddress newMemory = mapOn(osAddress, size);
PlatformAddress.memorySpy.alloc(newMemory);
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/ErrorCodeException.java b/luni/src/main/java/org/apache/harmony/luni/util/ErrorCodeException.java
deleted file mode 100644
index 92258ef..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/util/ErrorCodeException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.util;
-
-public class ErrorCodeException extends Exception {
-
- private static final long serialVersionUID = -8716868971626579265L;
-
- private int errorCode;
-
- public ErrorCodeException(int errorCode){
- this.errorCode = errorCode;
- }
-
- public int getErrorCode(){
- return errorCode;
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
index 280a8f5..b6cbcef 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
+++ b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
@@ -38,7 +38,7 @@
K0020=Unknown format
K002b=Unknown pattern character - '{0}'
K002c=Access denied {0}
-K002e=Offset out of bounds
+K002e=Offset out of bounds \: {0}
K002f=Arguments out of bounds
K0032=Address null or destination port out of range
K0033=Unknown socket type
@@ -326,3 +326,6 @@
KA028=Cannot set protocol version when stream in use
KA029=Can't find resource for bundle {0}, key {1}
KA030=Write end dead
+K0031=Length out of bounds \: {0}
+K0032=Source size {0} does not fit into destination
+K0033=Start index ({0}) is greater than end index ({1})
diff --git a/luni/src/main/native/cbigint.c b/luni/src/main/native/cbigint.c
index d327940..92b2992 100644
--- a/luni/src/main/native/cbigint.c
+++ b/luni/src/main/native/cbigint.c
@@ -253,6 +253,34 @@
}
}
+#ifndef HY_LITTLE_ENDIAN
+void simpleMultiplyAddHighPrecisionBigEndianFix(U_64 *arg1, IDATA length, U_64 arg2, U_32 *result) {
+ /* Assumes result can hold the product and arg2 only holds 32 bits
+ of information */
+ U_64 product;
+ IDATA index, resultIndex;
+
+ index = resultIndex = 0;
+ product = 0;
+
+ do {
+ product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * LOW_U32_FROM_PTR(arg1 + index);
+ result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product);
+ ++resultIndex;
+ product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * HIGH_U32_FROM_PTR(arg1 + index);
+ result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product);
+ ++resultIndex;
+ } while (++index < length);
+
+ result[halfAt(resultIndex)] += HIGH_U32_FROM_VAR(product);
+ if (result[halfAt(resultIndex)] < HIGH_U32_FROM_VAR(product)) {
+ /* must be careful with ++ operator and macro expansion */
+ ++resultIndex;
+ while (++result[halfAt(resultIndex)] == 0) ++resultIndex;
+ }
+}
+#endif
+
void
multiplyHighPrecision (U_64 * arg1, IDATA length1, U_64 * arg2, IDATA length2,
U_64 * result, IDATA length)
@@ -281,10 +309,11 @@
{
simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]),
resultIn32 + (++index));
- simpleMultiplyAddHighPrecision (arg1, length1,
- HIGH_IN_U64 (arg2[count]),
- resultIn32 + (++index));
-
+#ifdef HY_LITTLE_ENDIAN
+ simpleMultiplyAddHighPrecision(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index));
+#else
+ simpleMultiplyAddHighPrecisionBigEndianFix(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index));
+#endif
}
}
diff --git a/luni/src/main/native/fltconst.h b/luni/src/main/native/fltconst.h
index 03a97cd..940d5fc 100644
--- a/luni/src/main/native/fltconst.h
+++ b/luni/src/main/native/fltconst.h
@@ -140,16 +140,23 @@
#define SET_PINF_SNGL_PTR(fltptr) *U32P((fltptr)) = SINGLE_EXPONENT_MASK
#define SET_NINF_SNGL_PTR(fltptr) *U32P((fltptr)) = (SINGLE_EXPONENT_MASK | SINGLE_SIGN_MASK)
-/* on some platforms (HP720) we cannot reference an unaligned float. Build them by hand, one U_32 at a time. */
-#if defined(ATOMIC_FLOAT_ACCESS)
-#define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(dstPtr) = HIGH_U32_FROM_DBL_PTR(aDoublePtr); LOW_U32_FROM_DBL_PTR(dstPtr) = LOW_U32_FROM_DBL_PTR(aDoublePtr)
-#define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(aDoublePtr) = HIGH_U32_FROM_DBL_PTR(dstPtr); LOW_U32_FROM_DBL_PTR(aDoublePtr) = LOW_U32_FROM_DBL_PTR(dstPtr)
+#if defined(HY_WORD64)
+ #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) ((U64U32DBL *)(aDoublePtr))->u64val = ((U64U32DBL *)(dstPtr))->u64val
+ #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) ((U64U32DBL *)(dstPtr))->u64val = ((U64U32DBL *)(aDoublePtr))->u64val
+ #define STORE_LONG(dstPtr, hi, lo) ((U64U32DBL *)(dstPtr))->u64val = (((U_64)(hi)) << 32) | (lo)
#else
-#define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) (*(dstPtr) = *(aDoublePtr))
-#define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) (*(aDoublePtr) = *(dstPtr))
-#endif
+ /* on some platforms (HP720) we cannot reference an unaligned float. Build them by hand, one U_32 at a time. */
+ #if defined(ATOMIC_FLOAT_ACCESS)
+ #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(dstPtr) = HIGH_U32_FROM_DBL_PTR(aDoublePtr); LOW_U32_FROM_DBL_PTR(dstPtr) = LOW_U32_FROM_DBL_PTR(aDoublePtr)
+ #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) HIGH_U32_FROM_DBL_PTR(aDoublePtr) = HIGH_U32_FROM_DBL_PTR(dstPtr); LOW_U32_FROM_DBL_PTR(aDoublePtr) = LOW_U32_FROM_DBL_PTR(dstPtr)
+ #else
+ #define PTR_DOUBLE_STORE(dstPtr, aDoublePtr) (*(dstPtr) = *(aDoublePtr))
+ #define PTR_DOUBLE_VALUE(dstPtr, aDoublePtr) (*(aDoublePtr) = *(dstPtr))
+ #endif
-#define STORE_LONG(dstPtr, hi, lo) HIGH_U32_FROM_LONG64_PTR(dstPtr) = (hi); LOW_U32_FROM_LONG64_PTR(dstPtr) = (lo)
+ #define STORE_LONG(dstPtr, hi, lo) HIGH_U32_FROM_LONG64_PTR(dstPtr) = (hi); LOW_U32_FROM_LONG64_PTR(dstPtr) = (lo)
+#endif /* HY_WORD64 */
+
#define PTR_SINGLE_VALUE(dstPtr, aSinglePtr) (*U32P(aSinglePtr) = *U32P(dstPtr))
#define PTR_SINGLE_STORE(dstPtr, aSinglePtr) *((U_32 *)(dstPtr)) = (*U32P(aSinglePtr))
diff --git a/luni/src/main/native/java_net_InetAddress.cpp b/luni/src/main/native/java_net_InetAddress.cpp
index d7b4931..2af493c 100644
--- a/luni/src/main/native/java_net_InetAddress.cpp
+++ b/luni/src/main/native/java_net_InetAddress.cpp
@@ -24,12 +24,9 @@
#include <stdio.h>
#include <string.h>
-#include <assert.h>
#include <netdb.h>
#include <errno.h>
-#include <cutils/properties.h>
-#include <cutils/adb_networking.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
@@ -48,19 +45,6 @@
}
}
-static void throwNullPointerException(JNIEnv* env)
-{
- const char* className = "java/lang/NullPointerException";
-
- jclass exClass = env->FindClass(className);
-
- if (exClass == NULL) {
- LOGE("Unable to find class %s", className);
- } else {
- env->ThrowNew(exClass, NULL);
- }
-}
-
#if LOG_DNS
static void logIpString(struct addrinfo* ai, const char* name)
{
@@ -80,33 +64,6 @@
}
#endif
-static jobjectArray getAllByNameUsingAdb(JNIEnv* env, const char* name)
-{
- struct in_addr outaddr;
- jobjectArray addressArray = NULL;
- jbyteArray byteArray;
-
-#if 0
- LOGI("ADB networking: -gethostbyname err %d addr 0x%08x %u.%u.%u.%u",
- err, (unsigned int)outaddr.a.s_addr,
- outaddr.j[0],outaddr.j[1],
- outaddr.j[2],outaddr.j[3]);
-#endif
-
- if (adb_networking_gethostbyname(name, &outaddr) >= 0) {
- addressArray = env->NewObjectArray(1, byteArrayClass, NULL);
- byteArray = env->NewByteArray(4);
- if (addressArray && byteArray) {
- env->SetByteArrayRegion(byteArray, 0, 4, (jbyte*) &outaddr.s_addr);
- env->SetObjectArrayElement(addressArray, 1, byteArray);
- }
- } else {
- jniThrowException(env, "java/net/UnknownHostException", "adb error");
- }
-
- return addressArray;
-}
-
static jobjectArray getAllByNameUsingDns(JNIEnv* env, const char* name,
jboolean preferIPv4Stack)
{
@@ -208,28 +165,12 @@
jboolean preferIPv4Stack)
{
if (javaName == NULL) {
- throwNullPointerException(env);
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
return NULL;
}
const char* name = env->GetStringUTFChars(javaName, NULL);
- jobjectArray out = NULL;
-
- char useAdbNetworkingProperty[PROPERTY_VALUE_MAX];
- char adbConnected[PROPERTY_VALUE_MAX];
- property_get("android.net.use-adb-networking",
- useAdbNetworkingProperty, "");
- property_get("adb.connected",
- adbConnected, "");
-
- // Any non-empty string value for use-adb-networking is considered "set"
- if ((strlen(useAdbNetworkingProperty) > 0)
- && (strlen(adbConnected) > 0) ) {
- out = getAllByNameUsingAdb(env, name);
- } else {
- out = getAllByNameUsingDns(env, name, preferIPv4Stack);
- }
-
+ jobjectArray out = getAllByNameUsingDns(env, name, preferIPv4Stack);
env->ReleaseStringUTFChars(javaName, name);
return out;
}
@@ -247,57 +188,44 @@
jbyteArray javaAddress)
{
if (javaAddress == NULL) {
- throwNullPointerException(env);
- return NULL;
- }
-
- size_t addrlen = env->GetArrayLength(javaAddress);
- jbyte* rawAddress = env->GetByteArrayElements(javaAddress, NULL);
- if (rawAddress == NULL) {
- throwNullPointerException(env);
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
return NULL;
}
// Convert the raw address bytes into a socket address structure.
- int ret = 0;
struct sockaddr_storage ss;
- struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss;
- size_t socklen;
memset(&ss, 0, sizeof(ss));
- switch (addrlen) {
- case 4:
- socklen = sizeof(struct sockaddr_in);
- sin->sin_family = AF_INET;
- memcpy(&sin->sin_addr.s_addr, rawAddress, addrlen);
- env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT);
- break;
- case 16:
- socklen = sizeof(struct sockaddr_in6);
- sin6->sin6_family = AF_INET6;
- memcpy(&sin6->sin6_addr.s6_addr, rawAddress, addrlen);
- env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT);
- break;
- default:
- // The caller already throws an exception in this case. Don't worry
- // about it here.
- env->ReleaseByteArrayElements(javaAddress, rawAddress, JNI_ABORT);
- return NULL;
+
+ size_t socklen;
+ const size_t addressLength = env->GetArrayLength(javaAddress);
+ if (addressLength == 4) {
+ struct sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&ss);
+ sin->sin_family = AF_INET;
+ socklen = sizeof(struct sockaddr_in);
+ jbyte* dst = reinterpret_cast<jbyte*>(&sin->sin_addr.s_addr);
+ env->GetByteArrayRegion(javaAddress, 0, 4, dst);
+ } else if (addressLength == 16) {
+ struct sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6*>(&ss);
+ sin6->sin6_family = AF_INET6;
+ socklen = sizeof(struct sockaddr_in6);
+ jbyte* dst = reinterpret_cast<jbyte*>(&sin6->sin6_addr.s6_addr);
+ env->GetByteArrayRegion(javaAddress, 0, 16, dst);
+ } else {
+ // The caller already throws an exception in this case. Don't worry
+ // about it here.
+ return NULL;
}
// Look up the host name from the IP address.
char name[NI_MAXHOST];
- if (ret == 0) {
- ret = getnameinfo((struct sockaddr *) &ss, socklen, name, sizeof(name),
- NULL, 0, NI_NAMEREQD);
+ int ret = getnameinfo(reinterpret_cast<sockaddr*>(&ss), socklen,
+ name, sizeof(name), NULL, 0, NI_NAMEREQD);
+ if (ret != 0) {
+ jniThrowException(env, "java/net/UnknownHostException", gai_strerror(ret));
+ return NULL;
}
- if (ret == 0) {
- return env->NewStringUTF(name);
- }
-
- jniThrowException(env, "java/net/UnknownHostException", gai_strerror(ret));
- return NULL;
+ return env->NewStringUTF(name);
}
/*
diff --git a/luni/src/main/native/java_net_NetworkInterface.c b/luni/src/main/native/java_net_NetworkInterface.c
deleted file mode 100644
index db6d503..0000000
--- a/luni/src/main/native/java_net_NetworkInterface.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNIHelp.h"
-#include "jni.h"
-#include "errno.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <sys/ioctl.h>
-
-//--------------------------------------------------------------------
-// TODO copied from OSNetworkSystem. Might get into a separate .h file
-/**
- * Throws an IOException with the given message.
- */
-static void throwSocketException(JNIEnv *env, const char *message) {
- jclass exClass = (*env)->FindClass(env, "java/net/SocketException");
-
- if(exClass == NULL) {
- LOGE("Unable to find class java/net/SocketException");
- } else {
- (*env)->ThrowNew(env, exClass, message);
- }
-}
-
-
-/**
- * Throws a NullPointerException.
- */
-static void throwNullPointerException(JNIEnv *env) {
- jclass exClass = (*env)->FindClass(env, "java/lang/NullPointerException");
-
- if(exClass == NULL) {
- LOGE("Unable to find class java/lang/NullPointerException");
- } else {
- (*env)->ThrowNew(env, exClass, NULL);
- }
-}
-
-/**
- * @name Socket Errors
- * Error codes for socket operations
- *
- * @internal SOCKERR* range from -200 to -299 avoid overlap
- */
-#define SOCKERR_BADSOCKET -200 /* generic error */
-#define SOCKERR_NOTINITIALIZED -201 /* socket library uninitialized */
-#define SOCKERR_BADAF -202 /* bad address family */
-#define SOCKERR_BADPROTO -203 /* bad protocol */
-#define SOCKERR_BADTYPE -204 /* bad type */
-#define SOCKERR_SYSTEMBUSY -205 /* system busy handling requests */
-#define SOCKERR_SYSTEMFULL -206 /* too many sockets */
-#define SOCKERR_NOTCONNECTED -207 /* socket is not connected */
-#define SOCKERR_INTERRUPTED -208 /* the call was cancelled */
-#define SOCKERR_TIMEOUT -209 /* the operation timed out */
-#define SOCKERR_CONNRESET -210 /* the connection was reset */
-#define SOCKERR_WOULDBLOCK -211 /* the socket is marked as nonblocking operation would block */
-#define SOCKERR_ADDRNOTAVAIL -212 /* address not available */
-#define SOCKERR_ADDRINUSE -213 /* address already in use */
-#define SOCKERR_NOTBOUND -214 /* the socket is not bound */
-#define SOCKERR_UNKNOWNSOCKET -215 /* resolution of fileDescriptor to socket failed */
-#define SOCKERR_INVALIDTIMEOUT -216 /* the specified timeout is invalid */
-#define SOCKERR_FDSETFULL -217 /* Unable to create an FDSET */
-#define SOCKERR_TIMEVALFULL -218 /* Unable to create a TIMEVAL */
-#define SOCKERR_REMSOCKSHUTDOWN -219 /* The remote socket has shutdown gracefully */
-#define SOCKERR_NOTLISTENING -220 /* listen() was not invoked prior to accept() */
-#define SOCKERR_NOTSTREAMSOCK -221 /* The socket does not support connection-oriented service */
-#define SOCKERR_ALREADYBOUND -222 /* The socket is already bound to an address */
-#define SOCKERR_NBWITHLINGER -223 /* The socket is marked non-blocking & SO_LINGER is non-zero */
-#define SOCKERR_ISCONNECTED -224 /* The socket is already connected */
-#define SOCKERR_NOBUFFERS -225 /* No buffer space is available */
-#define SOCKERR_HOSTNOTFOUND -226 /* Authoritative Answer Host not found */
-#define SOCKERR_NODATA -227 /* Valid name, no data record of requested type */
-#define SOCKERR_BOUNDORCONN -228 /* The socket has not been bound or is already connected */
-#define SOCKERR_OPNOTSUPP -229 /* The socket does not support the operation */
-#define SOCKERR_OPTUNSUPP -230 /* The socket option is not supported */
-#define SOCKERR_OPTARGSINVALID -231 /* The socket option arguments are invalid */
-#define SOCKERR_SOCKLEVELINVALID -232 /* The socket level is invalid */
-#define SOCKERR_TIMEOUTFAILURE -233
-#define SOCKERR_SOCKADDRALLOCFAIL -234 /* Unable to allocate the sockaddr structure */
-#define SOCKERR_FDSET_SIZEBAD -235 /* The calculated maximum size of the file descriptor set is bad */
-#define SOCKERR_UNKNOWNFLAG -236 /* The flag is unknown */
-#define SOCKERR_MSGSIZE -237 /* The datagram was too big to fit the specified buffer & was truncated. */
-#define SOCKERR_NORECOVERY -238 /* The operation failed with no recovery possible */
-#define SOCKERR_ARGSINVALID -239 /* The arguments are invalid */
-#define SOCKERR_BADDESC -240 /* The socket argument is not a valid file descriptor */
-#define SOCKERR_NOTSOCK -241 /* The socket argument is not a socket */
-#define SOCKERR_HOSTENTALLOCFAIL -242 /* Unable to allocate the hostent structure */
-#define SOCKERR_TIMEVALALLOCFAIL -243 /* Unable to allocate the timeval structure */
-#define SOCKERR_LINGERALLOCFAIL -244 /* Unable to allocate the linger structure */
-#define SOCKERR_IPMREQALLOCFAIL -245 /* Unable to allocate the ipmreq structure */
-#define SOCKERR_FDSETALLOCFAIL -246 /* Unable to allocate the fdset structure */
-#define SOCKERR_OPFAILED -247
-#define SOCKERR_VALUE_NULL -248 /* The value indexed was NULL */
-#define SOCKERR_CONNECTION_REFUSED -249 /* connection was refused */
-#define SOCKERR_ENETUNREACH -250 /* network is not reachable */
-#define SOCKERR_EACCES -251 /* permissions do not allow action on socket */
-
-/**
- * Answer the errorString corresponding to the errorNumber, if available.
- * This function will answer a default error string, if the errorNumber is not
- * recognized.
- *
- * This function will have to be reworked to handle internationalization properly, removing
- * the explicit strings.
- *
- * @param anErrorNum the error code to resolve to a human readable string
- *
- * @return a human readable error string
- */
-
-static char * netLookupErrorString(int anErrorNum) {
- switch(anErrorNum) {
- case SOCKERR_BADSOCKET:
- return "Bad socket";
- case SOCKERR_NOTINITIALIZED:
- return "Socket library uninitialized";
- case SOCKERR_BADAF:
- return "Bad address family";
- case SOCKERR_BADPROTO:
- return "Bad protocol";
- case SOCKERR_BADTYPE:
- return "Bad type";
- case SOCKERR_SYSTEMBUSY:
- return "System busy handling requests";
- case SOCKERR_SYSTEMFULL:
- return "Too many sockets allocated";
- case SOCKERR_NOTCONNECTED:
- return "Socket is not connected";
- case SOCKERR_INTERRUPTED:
- return "The call was cancelled";
- case SOCKERR_TIMEOUT:
- return "The operation timed out";
- case SOCKERR_CONNRESET:
- return "The connection was reset";
- case SOCKERR_WOULDBLOCK:
- return "The socket is marked as nonblocking operation would block";
- case SOCKERR_ADDRNOTAVAIL:
- return "The address is not available";
- case SOCKERR_ADDRINUSE:
- return "The address is already in use";
- case SOCKERR_NOTBOUND:
- return "The socket is not bound";
- case SOCKERR_UNKNOWNSOCKET:
- return "Resolution of the FileDescriptor to socket failed";
- case SOCKERR_INVALIDTIMEOUT:
- return "The specified timeout is invalid";
- case SOCKERR_FDSETFULL:
- return "Unable to create an FDSET";
- case SOCKERR_TIMEVALFULL:
- return "Unable to create a TIMEVAL";
- case SOCKERR_REMSOCKSHUTDOWN:
- return "The remote socket has shutdown gracefully";
- case SOCKERR_NOTLISTENING:
- return "Listen() was not invoked prior to accept()";
- case SOCKERR_NOTSTREAMSOCK:
- return "The socket does not support connection-oriented service";
- case SOCKERR_ALREADYBOUND:
- return "The socket is already bound to an address";
- case SOCKERR_NBWITHLINGER:
- return "The socket is marked non-blocking & SO_LINGER is non-zero";
- case SOCKERR_ISCONNECTED:
- return "The socket is already connected";
- case SOCKERR_NOBUFFERS:
- return "No buffer space is available";
- case SOCKERR_HOSTNOTFOUND:
- return "Authoritative Answer Host not found";
- case SOCKERR_NODATA:
- return "Valid name, no data record of requested type";
- case SOCKERR_BOUNDORCONN:
- return "The socket has not been bound or is already connected";
- case SOCKERR_OPNOTSUPP:
- return "The socket does not support the operation";
- case SOCKERR_OPTUNSUPP:
- return "The socket option is not supported";
- case SOCKERR_OPTARGSINVALID:
- return "The socket option arguments are invalid";
- case SOCKERR_SOCKLEVELINVALID:
- return "The socket level is invalid";
- case SOCKERR_TIMEOUTFAILURE:
- return "The timeout operation failed";
- case SOCKERR_SOCKADDRALLOCFAIL:
- return "Failed to allocate address structure";
- case SOCKERR_FDSET_SIZEBAD:
- return "The calculated maximum size of the file descriptor set is bad";
- case SOCKERR_UNKNOWNFLAG:
- return "The flag is unknown";
- case SOCKERR_MSGSIZE:
- return "The datagram was too big to fit the specified buffer, so truncated";
- case SOCKERR_NORECOVERY:
- return "The operation failed with no recovery possible";
- case SOCKERR_ARGSINVALID:
- return "The arguments are invalid";
- case SOCKERR_BADDESC:
- return "The socket argument is not a valid file descriptor";
- case SOCKERR_NOTSOCK:
- return "The socket argument is not a socket";
- case SOCKERR_HOSTENTALLOCFAIL:
- return "Unable to allocate the hostent structure";
- case SOCKERR_TIMEVALALLOCFAIL:
- return "Unable to allocate the timeval structure";
- case SOCKERR_LINGERALLOCFAIL:
- return "Unable to allocate the linger structure";
- case SOCKERR_IPMREQALLOCFAIL:
- return "Unable to allocate the ipmreq structure";
- case SOCKERR_FDSETALLOCFAIL:
- return "Unable to allocate the fdset structure";
- case SOCKERR_CONNECTION_REFUSED:
- return "Connection refused";
-
- default:
- return "unkown error";
- }
-}
-
-/**
- * Converts a native address structure to a 4-byte array. Throws a
- * NullPointerException or an IOException in case of error. This is
- * signaled by a return value of -1. The normal return value is 0.
- */
-static int structInToJavaAddress(
- JNIEnv *env, struct in_addr *address, jbyteArray java_address) {
-
- if(java_address == NULL) {
- throwNullPointerException(env);
- return -1;
- }
-
- if((*env)->GetArrayLength(env, java_address) != sizeof(address->s_addr)) {
- jniThrowIOException(env, errno);
- return -1;
- }
-
- jbyte *java_address_bytes;
-
- java_address_bytes = (*env)->GetByteArrayElements(env, java_address, NULL);
-
- memcpy(java_address_bytes, &(address->s_addr), sizeof(address->s_addr));
-
- (*env)->ReleaseByteArrayElements(env, java_address, java_address_bytes, 0);
-
- return 0;
-}
-
-static jobject structInToInetAddress(JNIEnv *env, struct in_addr *address) {
- jbyteArray bytes;
- int success;
-
- bytes = (*env)->NewByteArray(env, 4);
-
- if(bytes == NULL) {
- return NULL;
- }
-
- success = structInToJavaAddress(env, address, bytes);
-
- if(success < 0) {
- return NULL;
- }
-
- jclass iaddrclass = (*env)->FindClass(env, "java/net/InetAddress");
-
- if(iaddrclass == NULL) {
- LOGE("Can't find java/net/InetAddress");
- jniThrowException(env, "java/lang/ClassNotFoundException", "java.net.InetAddress");
- return NULL;
- }
-
- jmethodID iaddrgetbyaddress = (*env)->GetStaticMethodID(env, iaddrclass, "getByAddress", "([B)Ljava/net/InetAddress;");
-
- if(iaddrgetbyaddress == NULL) {
- LOGE("Can't find method InetAddress.getByAddress(byte[] val)");
- jniThrowException(env, "java/lang/NoSuchMethodError", "InetAddress.getByAddress(byte[] val)");
- return NULL;
- }
-
- return (*env)->CallStaticObjectMethod(env, iaddrclass, iaddrgetbyaddress, bytes);
-}
-//--------------------------------------------------------------------
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* structure for returning either and IPV4 or IPV6 ip address */
-typedef struct ipAddress_struct {
- union {
- char bytes[sizeof(struct in_addr)];
- struct in_addr inAddr;
- } addr;
- unsigned int length;
- unsigned int scope;
-} ipAddress_struct;
-
-/* structure for returning network interface information */
-typedef struct NetworkInterface_struct {
- char *name;
- char *displayName;
- unsigned int numberAddresses;
- unsigned int index;
- struct ipAddress_struct *addresses;
-} NetworkInterface_struct;
-
-/* array of network interface structures */
-typedef struct NetworkInterfaceArray_struct {
- unsigned int length;
- struct NetworkInterface_struct *elements;
-} NetworkInterfaceArray_struct;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Frees the memory allocated for the hyNetworkInterface_struct array passed in
- *
- * @param[in] portLibrary The port library.
- * @param[in] handle Pointer to array of network interface structures to be freed
- *
- * @return 0 on success
-*/
-int sock_free_network_interface_struct (struct NetworkInterfaceArray_struct *array) {
- unsigned int i = 0;
-
- if((array != NULL) && (array->elements != NULL)) {
-
- /* free the allocated memory in each of the structures */
- for(i = 0; i < array->length; i++) {
-
- /* free the name, displayName and addresses */
- if(array->elements[i].name != NULL) {
- free(array->elements[i].name);
- }
-
- if(array->elements[i].displayName != NULL) {
- free(array->elements[i].displayName);
- }
-
- if(array->elements[i].addresses != NULL) {
- free(array->elements[i].addresses);
- }
- }
-
- /* now free the array itself */
- free(array->elements);
- }
-
- return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Queries and returns the information for the network interfaces that are currently active within the system.
- * Applications are responsible for freeing the memory returned via the handle.
- *
- * @param[in] portLibrary The port library.
- * @param[in,out] array Pointer to structure with array of network interface entries
- * @param[in] boolean which indicates if we should prefer the IPv4 stack or not
- *
- * @return The number of elements in handle on success, negatvie portable error code on failure.
- -WSANO_RECOVERY if system calls required to get the info fail, -WSAENOBUFS if memory allocation fails
- * @note A return value of 0 indicates no interfaces exist
-*/
-int sockGetNetworkInterfaces(struct NetworkInterfaceArray_struct * array) {
-
- struct NetworkInterface_struct *interfaces = NULL;
- unsigned int nameLength = 0;
- unsigned int currentAdapterIndex = 0;
- unsigned int counter = 0;
- unsigned int result = 0;
- unsigned int numAddresses = 0;
- unsigned int currentIPAddressIndex = 0;
- unsigned int numAdapters = 0;
- int err = 0;
-
- struct ifconf ifc;
- int len = 32 * sizeof(struct ifreq);
- int socketP = 0;
- unsigned int totalInterfaces = 0;
- struct ifreq reqCopy;
- unsigned int counter2 = 0;
- char *lastName = NULL;
-
- int ifconfCommand = SIOCGIFCONF;
-
- /* this method is not guarranteed to return the IPV6 addresses. Code is include so that if the platform returns IPV6 addresses
- in reply to the SIOCGIFCONF they will be included. Howerver, it is not guarranteed or even expected that many platforms will
- include the IPV6 addresses. For this reason there are other specific implementations that will return the IPV6 addresses */
- /* first get the list of interfaces. We do not know how long the buffer needs to be so we try with one that allows for
- 32 interfaces. If this turns out not to be big enough then we expand the buffer to be able to support another
- 32 interfaces and try again. We do this until the result indicates that the result fit into the buffer provided */
- /* we need socket to do the ioctl so create one */
- socketP = socket(PF_INET, SOCK_DGRAM, 0);
- if(socketP < 0) {
- return socketP;
- }
- for(;;) {
- char *data = (char *)malloc(len * sizeof(char));
- if(data == NULL) {
- close(socketP);
- return SOCKERR_NOBUFFERS;
- }
- ifc.ifc_len = len;
- ifc.ifc_buf = data;
- errno = 0;
- if(ioctl(socketP, ifconfCommand, &ifc) != 0) {
- err = errno;
- free(ifc.ifc_buf);
- close(socketP);
- return SOCKERR_NORECOVERY;
- }
- if(ifc.ifc_len < len)
- break;
- /* the returned data was likely truncated, expand the buffer and try again */
- free(ifc.ifc_buf);
- len += 32 * sizeof(struct ifreq);
- }
-
- /* get the number of distinct interfaces */
- if(ifc.ifc_len != 0) {
- totalInterfaces = ifc.ifc_len / sizeof(struct ifreq);
- }
- lastName = NULL;
- for(counter = 0; counter < totalInterfaces; counter++) {
- if((NULL == lastName) || (strncmp(lastName, ifc.ifc_req[counter].ifr_name, IFNAMSIZ) != 0)) {
- /* make sure the interface is up */
- reqCopy = ifc.ifc_req[counter];
- ioctl(socketP, SIOCGIFFLAGS, &reqCopy);
- if((reqCopy.ifr_flags) & (IFF_UP == IFF_UP)) {
- numAdapters++;
- }
- }
- lastName = ifc.ifc_req[counter].ifr_name;
- }
-
- /* now allocate the space for the hyNetworkInterface structs and fill it in */
- interfaces = malloc(numAdapters * sizeof(NetworkInterface_struct));
- if(NULL == interfaces) {
- free(ifc.ifc_buf);
- close(socketP);
- return SOCKERR_NOBUFFERS;
- }
-
- /* initialize the structure so that we can free allocated if a failure occurs */
- for(counter = 0; counter < numAdapters; counter++) {
- interfaces[counter].name = NULL;
- interfaces[counter].displayName = NULL;
- interfaces[counter].addresses = NULL;
- }
-
- /* set up the return stucture */
- array->elements = interfaces;
- array->length = numAdapters;
- lastName = NULL;
- for(counter = 0; counter < totalInterfaces; counter++) {
- /* make sure the interface is still up */
- reqCopy = ifc.ifc_req[counter];
- ioctl(socketP, SIOCGIFFLAGS, &reqCopy);
- if((reqCopy.ifr_flags) & (IFF_UP == IFF_UP)) {
- /* since this function can return multiple entries for the same name, only do it for the first one with any given name */
- if((NULL == lastName) || (strncmp(lastName, ifc.ifc_req[counter].ifr_name, IFNAMSIZ) != 0)) {
-
- /* get the index for the interface */
- interfaces[currentAdapterIndex].index =
- ifc.ifc_req[counter].ifr_ifindex;
- /* get the name and display name for the adapter */
- /* there only seems to be one name so use it for both the name and the display name */
- nameLength = strlen(ifc.ifc_req[counter].ifr_name);
- interfaces[currentAdapterIndex].name = malloc(nameLength + 1);
-
- if(NULL == interfaces[currentAdapterIndex].name) {
- free(ifc.ifc_buf);
- sock_free_network_interface_struct(array);
- close(socketP);
- return SOCKERR_NOBUFFERS;
- }
- strncpy(interfaces[currentAdapterIndex].name, ifc.ifc_req[counter].ifr_name, nameLength);
- interfaces[currentAdapterIndex].name[nameLength] = 0;
- nameLength = strlen(ifc.ifc_req[counter].ifr_name);
- interfaces[currentAdapterIndex].displayName = malloc(nameLength + 1);
- if(NULL == interfaces[currentAdapterIndex].displayName) {
- free(ifc.ifc_buf);
- sock_free_network_interface_struct(array);
- close(socketP);
- return SOCKERR_NOBUFFERS;
- }
- strncpy(interfaces[currentAdapterIndex].displayName, ifc.ifc_req[counter].ifr_name, nameLength);
- interfaces[currentAdapterIndex].displayName[nameLength] = 0;
-
- /* check how many addresses/aliases this adapter has. aliases show up as adaptors with the same name */
- numAddresses = 0;
- for(counter2 = counter; counter2 < totalInterfaces; counter2++) {
- if(strncmp(ifc.ifc_req[counter].ifr_name, ifc.ifc_req[counter2].ifr_name, IFNAMSIZ) == 0) {
- if(ifc.ifc_req[counter2].ifr_addr.sa_family == AF_INET) {
- numAddresses++;
- }
- } else {
- break;
- }
- }
-
- /* allocate space for the addresses */
- interfaces[currentAdapterIndex].numberAddresses = numAddresses;
- interfaces[currentAdapterIndex].addresses = malloc(numAddresses * sizeof(ipAddress_struct));
- if(NULL == interfaces[currentAdapterIndex].addresses) {
- free(ifc.ifc_buf);
- sock_free_network_interface_struct(array);
- close(socketP);
- return SOCKERR_NOBUFFERS;
- }
-
- /* now get the addresses */
- currentIPAddressIndex = 0;
- lastName = ifc.ifc_req[counter].ifr_name;
-
- for(;;) {
- if(ifc.ifc_req[counter].ifr_addr.sa_family == AF_INET) {
- interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].addr.inAddr.s_addr = ((struct sockaddr_in *) (&ifc.ifc_req[counter].ifr_addr))->sin_addr.s_addr;
- interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].length = sizeof(struct in_addr);
- interfaces[currentAdapterIndex].addresses[currentIPAddressIndex].scope = 0;
- currentIPAddressIndex++;
- }
-
- /* we mean to increment the outside counter here as we want to skip the next entry as it is for the same interface
- as we are currently working on */
- if((counter + 1 < totalInterfaces) && (strncmp(ifc.ifc_req[counter + 1].ifr_name, lastName, IFNAMSIZ) == 0)) {
- counter++;
- } else {
- break;
- }
-
- }
- currentAdapterIndex++;
- }
- }
- } /* for over all interfaces */
- /* now an interface might have been taken down since we first counted them */
- array->length = currentAdapterIndex;
- /* free the memory now that we are done with it */
- free(ifc.ifc_buf);
- close(socketP);
-
- return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Answer an array of NetworkInterface objects. One for each network interface within the system
- *
- * @param env pointer to the JNI library
- * @param clazz the class of the object invoking the JNI function
- *
- * @return an array of NetworkInterface objects of length 0 or more
- */
-
-static jobjectArray getNetworkInterfacesImpl(JNIEnv * env, jclass clazz) {
-
- /* variables to store network interfac edata returned by call to port library */
- struct NetworkInterfaceArray_struct networkInterfaceArray;
- int result = 0;
-
- /* variables for class and method objects needed to create bridge to java */
- jclass networkInterfaceClass = NULL;
- jclass inetAddressClass = NULL;
- jclass utilClass = NULL;
- jmethodID methodID = NULL;
- jmethodID utilMid = NULL;
-
- /* JNI objects used to return values from native call */
- jstring name = NULL;
- jstring displayName = NULL;
- jobjectArray addresses = NULL;
- jobjectArray networkInterfaces = NULL;
- jbyteArray bytearray = NULL;
-
- /* jobjects used to build the object arrays returned */
- jobject currentInterface = NULL;
- jobject element = NULL;
-
- /* misc variables needed for looping and determining inetAddress info */
- unsigned int i = 0;
- unsigned int j = 0;
- unsigned int nameLength = 0;
-
- /* get the classes and methods that we need for later calls */
- networkInterfaceClass = (*env)->FindClass(env, "java/net/NetworkInterface");
- if(networkInterfaceClass == NULL) {
- throwSocketException(env, netLookupErrorString(SOCKERR_NORECOVERY));
- return NULL;
- }
-
- inetAddressClass = (*env)->FindClass(env, "java/net/InetAddress");
- if(inetAddressClass == NULL) {
- throwSocketException(env, netLookupErrorString(SOCKERR_NORECOVERY));
- return NULL;
- }
-
- methodID = (*env)->GetMethodID(env, networkInterfaceClass, "<init>",
- "(Ljava/lang/String;Ljava/lang/String;[Ljava/net/InetAddress;I)V");
- if(methodID == NULL) {
- throwSocketException(env, netLookupErrorString(SOCKERR_NORECOVERY));
- return NULL;
- }
-
- utilClass = (*env)->FindClass(env, "org/apache/harmony/luni/util/Util");
- if(!utilClass) {
- return NULL;
- }
-
- utilMid = ((*env)->GetStaticMethodID(env, utilClass, "toString",
- "([BII)Ljava/lang/String;"));
- if(!utilMid) {
- return NULL;
- }
-
- result = sockGetNetworkInterfaces(&networkInterfaceArray);
-
- if(result < 0) {
- /* this means an error occured. The value returned is the socket error that should be returned */
- throwSocketException(env, netLookupErrorString(result));
- return NULL;
- }
-
- /* now loop through the interfaces and extract the information to be returned */
- for(j = 0; j < networkInterfaceArray.length; j++) {
- /* set the name and display name and reset the addresses object array */
- addresses = NULL;
- name = NULL;
- displayName = NULL;
-
- if(networkInterfaceArray.elements[j].name != NULL) {
- nameLength = strlen(networkInterfaceArray.elements[j].name);
- bytearray = (*env)->NewByteArray(env, nameLength);
- if(bytearray == NULL) {
- /* NewByteArray should have thrown an exception */
- return NULL;
- }
- (*env)->SetByteArrayRegion(env, bytearray, (jint) 0, nameLength,
- (jbyte *)networkInterfaceArray.elements[j].name);
- name = (*env)->CallStaticObjectMethod(env, utilClass, utilMid,
- bytearray, (jint) 0, nameLength);
- if((*env)->ExceptionCheck(env)) {
- return NULL;
- }
- }
-
- if(networkInterfaceArray.elements[j].displayName != NULL) {
- nameLength = strlen(networkInterfaceArray.elements[j].displayName);
- bytearray = (*env)->NewByteArray(env, nameLength);
- if(bytearray == NULL) {
- /* NewByteArray should have thrown an exception */
- return NULL;
- }
- (*env)->SetByteArrayRegion(env, bytearray, (jint) 0, nameLength,
- (jbyte *)networkInterfaceArray.elements[j].displayName);
- displayName = (*env)->CallStaticObjectMethod(env, utilClass, utilMid,
- bytearray, (jint) 0, nameLength);
- if((*env)->ExceptionCheck(env)) {
- return NULL;
- }
- }
-
- /* generate the object with the inet addresses for the itnerface */
- for(i = 0; i < networkInterfaceArray.elements[j].numberAddresses; i++) {
- element = structInToInetAddress(env, (struct in_addr *) &(networkInterfaceArray.elements[j].addresses[i].addr.inAddr));
- if(i == 0) {
- addresses = (*env)->NewObjectArray(env,
- networkInterfaceArray.elements[j].numberAddresses,
- inetAddressClass, element);
- } else {
- (*env)->SetObjectArrayElement(env, addresses, i, element);
- }
- }
-
- /* now create the NetworkInterface object for this interface and then add it it ot the arrary that will be returned */
- currentInterface = (*env)->NewObject(env, networkInterfaceClass,
- methodID, name, displayName, addresses,
- networkInterfaceArray.elements[j].index);
-
- if(j == 0) {
- networkInterfaces = (*env)->NewObjectArray(env,
- networkInterfaceArray.length, networkInterfaceClass,
- currentInterface);
- } else {
- (*env)->SetObjectArrayElement(env, networkInterfaces, j, currentInterface);
- }
- }
-
- /* free the memory for the interfaces struct and return the new NetworkInterface List */
- sock_free_network_interface_struct(&networkInterfaceArray);
- return networkInterfaces;
-}
-
-
-/*
- * JNI registration
- */
-static JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "getNetworkInterfacesImpl", "()[Ljava/net/NetworkInterface;", getNetworkInterfacesImpl }
-};
-int register_java_net_NetworkInterface(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "java/net/NetworkInterface",
- gMethods, NELEM(gMethods));
-
-}
diff --git a/luni/src/main/native/java_net_NetworkInterface.cpp b/luni/src/main/native/java_net_NetworkInterface.cpp
new file mode 100644
index 0000000..3ea6657
--- /dev/null
+++ b/luni/src/main/native/java_net_NetworkInterface.cpp
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AndroidSystemNatives.h"
+#include "JNIHelp.h"
+#include "jni.h"
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <net/if.h> // Note: Can't appear before <sys/socket.h> on OS X.
+
+// There are several ways that an interface index might be referenced
+// out of an ifreq struct, depending on the platform.
+#if defined(ifr_ifindex)
+// Linux: No need to do anything.
+#elif defined(ifr_index)
+#define ifr_ifindex ifr_index // BSD
+#elif defined(ifr_intval)
+#define ifr_ifindex ifr_intval // OS X
+#else
+#error "Unknown how to refer to an interface index on this platform."
+#endif
+
+// A smart pointer that closes the given fd on going out of scope.
+// TODO: make this generally available.
+class scoped_fd {
+public:
+ explicit scoped_fd(int fd) : fd(fd) {
+ }
+
+ ~scoped_fd() {
+ close(fd);
+ }
+
+ int get() const {
+ return fd;
+ }
+
+private:
+ int fd;
+};
+
+// TODO: add a header file for shared utilities like this.
+extern jobject socketAddressToInetAddress(JNIEnv* env, sockaddr_storage* sockAddress);
+
+class NetworkInterfaceGetter {
+public:
+ NetworkInterfaceGetter() : interfaces(NULL) {
+ // Initialize this so we can be responsible for deleting it.
+ ifc.ifc_buf = NULL;
+ }
+
+ ~NetworkInterfaceGetter() {
+ delete[] ifc.ifc_buf;
+ }
+
+ jobjectArray getNetworkInterfaces(JNIEnv* env);
+
+private:
+ jobjectArray interfaces;
+ ifconf ifc;
+};
+
+// TODO: move to JNIHelp?
+static void jniThrowOutOfMemoryError(JNIEnv* env) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", "native heap");
+}
+
+// TODO(enh): move to JNIHelp.h
+static void jniThrowSocketException(JNIEnv* env) {
+ char buf[BUFSIZ];
+ jniThrowException(env, "java/net/SocketException",
+ jniStrError(errno, buf, sizeof(buf)));
+}
+
+// Creates an InetAddress[] of size 'addressCount' from the ifc_req structs
+// starting at index 'startIndex' in 'ifc.ifc_req'.
+static jobjectArray MakeInetAddressArray(JNIEnv* env,
+ const ifconf& ifc, size_t startIndex, size_t addressCount) {
+ jclass inetAddressClass = env->FindClass("java/net/InetAddress");
+ if (inetAddressClass == NULL) {
+ return NULL;
+ }
+ jobjectArray addresses = env->NewObjectArray(addressCount, inetAddressClass, NULL);
+ if (addresses == NULL) {
+ return NULL;
+ }
+ for (size_t i = startIndex; i < startIndex + addressCount; ++i) {
+ sockaddr_storage* sockAddress =
+ reinterpret_cast<sockaddr_storage*>(&ifc.ifc_req[i].ifr_addr);
+ jobject element = socketAddressToInetAddress(env, sockAddress);
+ if (element == NULL) {
+ return NULL;
+ }
+ env->SetObjectArrayElement(addresses, i - startIndex, element);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+ }
+ return addresses;
+}
+
+// Creates a NetworkInterface with the given 'name', array of 'addresses',
+// and 'id'.
+static jobject MakeNetworkInterface(JNIEnv* env,
+ jstring name, jobjectArray addresses, jint id) {
+ jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
+ if (networkInterfaceClass == NULL) {
+ return NULL;
+ }
+ jmethodID networkInterfaceConstructor =
+ env->GetMethodID(networkInterfaceClass, "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;[Ljava/net/InetAddress;I)V");
+ if (networkInterfaceConstructor == NULL) {
+ return NULL;
+ }
+ return env->NewObject(networkInterfaceClass, networkInterfaceConstructor,
+ name, name, addresses, id);
+}
+
+jobjectArray NetworkInterfaceGetter::getNetworkInterfaces(JNIEnv* env) {
+ scoped_fd fd(socket(PF_INET, SOCK_DGRAM, 0));
+ if (fd.get() < 0) {
+ jniThrowSocketException(env);
+ return NULL;
+ }
+
+ // Get the list of interfaces.
+ // Keep trying larger buffers until the result fits.
+ int len = 32 * sizeof(ifreq);
+ for (;;) {
+ // TODO: std::vector or boost::scoped_array would make this less awful.
+ if (ifc.ifc_buf != NULL) {
+ delete[] ifc.ifc_buf;
+ ifc.ifc_buf = NULL;
+ }
+ char* data = new char[len];
+ if (data == NULL) {
+ jniThrowOutOfMemoryError(env);
+ return NULL;
+ }
+ ifc.ifc_len = len;
+ ifc.ifc_buf = data;
+ if (ioctl(fd.get(), SIOCGIFCONF, &ifc) != 0) {
+ jniThrowSocketException(env);
+ return NULL;
+ }
+ if (ifc.ifc_len < len) {
+ break;
+ }
+ // The returned data was likely truncated.
+ // Expand the buffer and try again.
+ len += 32 * sizeof(ifreq);
+ }
+
+ // Count the number of distinct interfaces.
+ // Multiple addresses for a given interface have the same interface name.
+ // This whole function assumes that all an interface's addresses will be
+ // listed adjacent to one another.
+ size_t totalAddressCount = ifc.ifc_len / sizeof(ifreq);
+ size_t interfaceCount = 0;
+ const char* lastName = NULL;
+ for (size_t i = 0; i < totalAddressCount; ++i) {
+ const char* name = ifc.ifc_req[i].ifr_name;
+ if (lastName == NULL || strncmp(lastName, name, IFNAMSIZ) != 0) {
+ ++interfaceCount;
+ }
+ lastName = name;
+ }
+
+ // Build the NetworkInterface[]...
+ jclass networkInterfaceClass = env->FindClass("java/net/NetworkInterface");
+ if (networkInterfaceClass == NULL) {
+ return NULL;
+ }
+ interfaces = env->NewObjectArray(interfaceCount, networkInterfaceClass, NULL);
+ if (interfaces == NULL) {
+ return NULL;
+ }
+
+ // Fill in the NetworkInterface[].
+ size_t arrayIndex = 0;
+ for (size_t i = 0; i < totalAddressCount; ++i) {
+ // Get the index for this interface.
+ // (This is an id the kernel uses, unrelated to our array indexes.)
+ int id = ifc.ifc_req[i].ifr_ifindex;
+
+ // Get the name for this interface. There only seems to be one name so
+ // we use it for both name and the display name (as does the RI).
+ jstring name = env->NewStringUTF(ifc.ifc_req[i].ifr_name);
+ if (name == NULL) {
+ return NULL;
+ }
+
+ // Check how many addresses this interface has.
+ size_t addressCount = 0;
+ for (size_t j = i; j < totalAddressCount; ++j) {
+ if (strncmp(ifc.ifc_req[i].ifr_name, ifc.ifc_req[j].ifr_name, IFNAMSIZ) == 0) {
+ if (ifc.ifc_req[j].ifr_addr.sa_family == AF_INET) {
+ ++addressCount;
+ }
+ } else {
+ break;
+ }
+ }
+
+ // Get this interface's addresses as an InetAddress[].
+ jobjectArray addresses = MakeInetAddressArray(env, ifc, i, addressCount);
+ if (addresses == NULL) {
+ return NULL;
+ }
+ // Create the NetworkInterface object and add it to the NetworkInterface[].
+ jobject interface = MakeNetworkInterface(env, name, addresses, id);
+ if (interface == NULL) {
+ return NULL;
+ }
+ env->SetObjectArrayElement(interfaces, arrayIndex++, interface);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+
+ // Skip over this interface's addresses to the next *interface*.
+ i += addressCount - 1;
+ }
+ return interfaces;
+}
+
+/**
+ * Returns an array of zero or more NetworkInterface objects, one for each
+ * network interface.
+ */
+static jobjectArray getNetworkInterfacesImpl(JNIEnv* env, jclass) {
+ NetworkInterfaceGetter getter;
+ return getter.getNetworkInterfaces(env);
+}
+
+/*
+ * JNI registration
+ */
+static JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ { "getNetworkInterfacesImpl", "()[Ljava/net/NetworkInterface;", (void*) getNetworkInterfacesImpl },
+};
+int register_java_net_NetworkInterface(JNIEnv* env) {
+ return jniRegisterNativeMethods(env, "java/net/NetworkInterface",
+ gMethods, NELEM(gMethods));
+}
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp
index 38f3d36..1e1893e 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp
@@ -14,401 +14,327 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+// BEGIN android-note
+// This file corresponds to harmony's OSFileSystem.c and OSFileSystemLinux32.c.
+// It has been greatly simplified by the assumption that the underlying
+// platform is always Linux.
+// END android-note
+
/*
* Common natives supporting the file system interface.
*/
#define HyMaxPath 1024
-#define HyOpenRead 1 /* Values for HyFileOpen */
+
+/* Values for HyFileOpen */
+#define HyOpenRead 1
#define HyOpenWrite 2
#define HyOpenCreate 4
#define HyOpenTruncate 8
#define HyOpenAppend 16
#define HyOpenText 32
-
/* Use this flag with HyOpenCreate, if this flag is specified then
- * trying to create an existing file will fail
+ * trying to create an existing file will fail
*/
#define HyOpenCreateNew 64
-#define HyOpenSync 128
+#define HyOpenSync 128
#define SHARED_LOCK_TYPE 1L
#include "JNIHelp.h"
#include "AndroidSystemNatives.h"
-#include <string.h>
-#include <stdio.h>
+#include <assert.h>
#include <errno.h>
-#include <stdlib.h>
-#include <sys/sendfile.h>
-#include <sys/uio.h>
#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/ioctl.h>
+#include <sys/uio.h>
-typedef struct socket_struct {
- int sock;
- unsigned short family;
-} socket_struct;
+#if HAVE_SYS_SENDFILE_H
+#include <sys/sendfile.h>
+#else
+/*
+ * Define a small adapter function: sendfile() isn't part of a standard,
+ * and its definition differs between Linux, BSD, and OS X. This version
+ * works for OS X but will probably not work on other BSDish systems.
+ * Note: We rely on function overloading here to define a same-named
+ * function with different arguments.
+ */
+#include <sys/socket.h>
+#include <sys/types.h>
+static inline ssize_t sendfile(int out_fd, int in_fd, off_t *offset,
+ size_t count) {
+ off_t len = count;
+ int result = sendfile(in_fd, out_fd, *offset, &len, NULL, 0);
+ if (result < 0) {
+ return -1;
+ }
+ return len;
+}
+#endif
static void convertToPlatform(char *path) {
char *pathIndex;
pathIndex = path;
while (*pathIndex != '\0') {
- if(*pathIndex == '\\') {
+ if (*pathIndex == '\\') {
*pathIndex = '/';
}
pathIndex++;
}
}
-static int
-EsTranslateOpenFlags(int flags) {
+static int EsTranslateOpenFlags(int flags) {
int realFlags = 0;
- if(flags & HyOpenAppend) {
+ if (flags & HyOpenAppend) {
realFlags |= O_APPEND;
}
- if(flags & HyOpenTruncate) {
+ if (flags & HyOpenTruncate) {
realFlags |= O_TRUNC;
}
- if(flags & HyOpenCreate) {
+ if (flags & HyOpenCreate) {
realFlags |= O_CREAT;
}
- if(flags & HyOpenCreateNew) {
+ if (flags & HyOpenCreateNew) {
realFlags |= O_EXCL | O_CREAT;
}
#ifdef O_SYNC
- if(flags & HyOpenSync) {
- realFlags |= O_SYNC;
- }
-#endif
- if(flags & HyOpenRead) {
- if(flags & HyOpenWrite) {
+ if (flags & HyOpenSync) {
+ realFlags |= O_SYNC;
+ }
+#endif
+ if (flags & HyOpenRead) {
+ if (flags & HyOpenWrite) {
return (O_RDWR | realFlags);
}
return (O_RDONLY | realFlags);
}
- if(flags & HyOpenWrite) {
+ if (flags & HyOpenWrite) {
return (O_WRONLY | realFlags);
}
return -1;
}
-/**
- * Lock the file identified by the given handle.
- * The range and lock type are given.
- */
-static jint harmony_io_lockImpl(JNIEnv * env, jobject thiz, jint handle,
- jlong start, jlong length, jint typeFlag, jboolean waitFlag) {
+// Checks whether we can safely treat the given jlong as an off_t without
+// accidental loss of precision.
+// TODO: this is bogus; we should use _FILE_OFFSET_BITS=64.
+static bool offsetTooLarge(JNIEnv* env, jlong longOffset) {
+ if (sizeof(off_t) >= sizeof(jlong)) {
+ // We're only concerned about the possibility that off_t is
+ // smaller than jlong. off_t is signed, so we don't need to
+ // worry about signed/unsigned.
+ return false;
+ }
- int rc;
- int waitMode = (waitFlag) ? F_SETLKW : F_SETLK;
+ // TODO: use std::numeric_limits<off_t>::max() and min() when we have them.
+ assert(sizeof(off_t) == sizeof(int));
+ static const off_t off_t_max = INT_MAX;
+ static const off_t off_t_min = INT_MIN;
+
+ if (longOffset > off_t_max || longOffset < off_t_min) {
+ // "Value too large for defined data type".
+ jniThrowIOException(env, EOVERFLOW);
+ return true;
+ }
+ return false;
+}
+
+static jlong translateLockLength(jlong length) {
+ // FileChannel.tryLock uses Long.MAX_VALUE to mean "lock the whole
+ // file", where POSIX would use 0. We can support that special case,
+ // even for files whose actual length we can't represent. For other
+ // out of range lengths, though, we want our range checking to fire.
+ return (length == 0x7fffffffffffffffLL) ? 0 : length;
+}
+
+static struct flock flockFromStartAndLength(jlong start, jlong length) {
struct flock lock;
-
memset(&lock, 0, sizeof(lock));
- // If start or length overflow the max values we can represent, then max them out.
- if(start > 0x7fffffffL) {
- start = 0x7fffffffL;
- }
- if(length > 0x7fffffffL) {
- length = 0x7fffffffL;
- }
-
lock.l_whence = SEEK_SET;
lock.l_start = start;
lock.l_len = length;
- if((typeFlag & SHARED_LOCK_TYPE) == SHARED_LOCK_TYPE) {
+ return lock;
+}
+
+static jint harmony_io_lockImpl(JNIEnv* env, jobject, jint handle,
+ jlong start, jlong length, jint typeFlag, jboolean waitFlag) {
+
+ length = translateLockLength(length);
+ if (offsetTooLarge(env, start) || offsetTooLarge(env, length)) {
+ return -1;
+ }
+
+ struct flock lock(flockFromStartAndLength(start, length));
+
+ if ((typeFlag & SHARED_LOCK_TYPE) == SHARED_LOCK_TYPE) {
lock.l_type = F_RDLCK;
} else {
lock.l_type = F_WRLCK;
}
- do {
- rc = fcntl(handle, waitMode, &lock);
- } while ((rc < 0) && (errno == EINTR));
-
- return (rc == -1) ? -1 : 0;
+ int waitMode = (waitFlag) ? F_SETLKW : F_SETLK;
+ return TEMP_FAILURE_RETRY(fcntl(handle, waitMode, &lock));
}
-/**
- * Unlocks the specified region of the file.
- */
-static jint harmony_io_unlockImpl(JNIEnv * env, jobject thiz, jint handle,
+static void harmony_io_unlockImpl(JNIEnv* env, jobject, jint handle,
jlong start, jlong length) {
- int rc;
- struct flock lock;
-
- memset(&lock, 0, sizeof(lock));
-
- // If start or length overflow the max values we can represent, then max them out.
- if(start > 0x7fffffffL) {
- start = 0x7fffffffL;
- }
- if(length > 0x7fffffffL) {
- length = 0x7fffffffL;
+ length = translateLockLength(length);
+ if (offsetTooLarge(env, start) || offsetTooLarge(env, length)) {
+ return;
}
- lock.l_whence = SEEK_SET;
- lock.l_start = start;
- lock.l_len = length;
+ struct flock lock(flockFromStartAndLength(start, length));
lock.l_type = F_UNLCK;
- do {
- rc = fcntl(handle, F_SETLKW, &lock);
- } while ((rc < 0) && (errno == EINTR));
-
- return (rc == -1) ? -1 : 0;
+ int rc = TEMP_FAILURE_RETRY(fcntl(handle, F_SETLKW, &lock));
+ if (rc == -1) {
+ jniThrowIOException(env, errno);
+ }
}
/**
* Returns the granularity of the starting address for virtual memory allocation.
* (It's the same as the page size.)
- * Class: org_apache_harmony_luni_platform_OSFileSystem
- * Method: getAllocGranularity
- * Signature: ()I
*/
-static jint harmony_io_getAllocGranularity(JNIEnv * env, jobject thiz) {
- static int allocGranularity = 0;
- if(allocGranularity == 0) {
- allocGranularity = getpagesize();
- }
+static jint harmony_io_getAllocGranularity(JNIEnv* env, jobject) {
+ static int allocGranularity = getpagesize();
return allocGranularity;
}
-/*
- * Class: org_apache_harmony_luni_platform_OSFileSystem
- * Method: readvImpl
- * Signature: (I[J[I[I)J
- */
-static jlong harmony_io_readvImpl(JNIEnv *env, jobject thiz, jint fd,
- jintArray jbuffers, jintArray joffsets, jintArray jlengths, jint size) {
-
- jboolean bufsCopied = JNI_FALSE;
- jboolean offsetsCopied = JNI_FALSE;
- jboolean lengthsCopied = JNI_FALSE;
- jint *bufs;
- jint *offsets;
- jint *lengths;
- int i = 0;
- long totalRead = 0;
- struct iovec *vectors = (struct iovec *)malloc(size * sizeof(struct iovec));
- if(vectors == NULL) {
- return -1;
+// Translate three Java int[]s to a native iovec[] for readv and writev.
+static iovec* initIoVec(JNIEnv* env,
+ jintArray jBuffers, jintArray jOffsets, jintArray jLengths, jint size) {
+ iovec* vectors = new iovec[size];
+ if (vectors == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", "native heap");
+ return NULL;
}
- bufs = env->GetIntArrayElements(jbuffers, &bufsCopied);
- offsets = env->GetIntArrayElements(joffsets, &offsetsCopied);
- lengths = env->GetIntArrayElements(jlengths, &lengthsCopied);
- while(i < size) {
- vectors[i].iov_base = (void *)((int)(bufs[i]+offsets[i]));
+ jint *buffers = env->GetIntArrayElements(jBuffers, NULL);
+ jint *offsets = env->GetIntArrayElements(jOffsets, NULL);
+ jint *lengths = env->GetIntArrayElements(jLengths, NULL);
+ for (int i = 0; i < size; ++i) {
+ vectors[i].iov_base = reinterpret_cast<void*>(buffers[i] + offsets[i]);
vectors[i].iov_len = lengths[i];
- i++;
}
- totalRead = readv(fd, vectors, size);
- if(bufsCopied) {
- env->ReleaseIntArrayElements(jbuffers, bufs, JNI_ABORT);
- }
- if(offsetsCopied) {
- env->ReleaseIntArrayElements(joffsets, offsets, JNI_ABORT);
- }
- if(lengthsCopied) {
- env->ReleaseIntArrayElements(jlengths, lengths, JNI_ABORT);
- }
- free(vectors);
- return totalRead;
+ env->ReleaseIntArrayElements(jBuffers, buffers, JNI_ABORT);
+ env->ReleaseIntArrayElements(jOffsets, offsets, JNI_ABORT);
+ env->ReleaseIntArrayElements(jLengths, lengths, JNI_ABORT);
+ return vectors;
}
-/*
- * Class: org_apache_harmony_luni_platform_OSFileSystem
- * Method: writevImpl
- * Signature: (I[J[I[I)J
- */
-static jlong harmony_io_writevImpl(JNIEnv *env, jobject thiz, jint fd,
- jintArray jbuffers, jintArray joffsets, jintArray jlengths, jint size) {
-
- jboolean bufsCopied = JNI_FALSE;
- jboolean offsetsCopied = JNI_FALSE;
- jboolean lengthsCopied = JNI_FALSE;
- jint *bufs;
- jint *offsets;
- jint *lengths;
- int i = 0;
- long totalRead = 0;
- struct iovec *vectors = (struct iovec *)malloc(size * sizeof(struct iovec));
- if(vectors == NULL) {
+static jlong harmony_io_readv(JNIEnv* env, jobject, jint fd,
+ jintArray jBuffers, jintArray jOffsets, jintArray jLengths, jint size) {
+ iovec* vectors = initIoVec(env, jBuffers, jOffsets, jLengths, size);
+ if (vectors == NULL) {
return -1;
}
- bufs = env->GetIntArrayElements(jbuffers, &bufsCopied);
- offsets = env->GetIntArrayElements(joffsets, &offsetsCopied);
- lengths = env->GetIntArrayElements(jlengths, &lengthsCopied);
- while(i < size) {
- vectors[i].iov_base = (void *)((int)(bufs[i]+offsets[i]));
- vectors[i].iov_len = lengths[i];
- i++;
+ long result = readv(fd, vectors, size);
+ if (result == -1) {
+ jniThrowIOException(env, errno);
}
- totalRead = writev(fd, vectors, size);
- if(bufsCopied) {
- env->ReleaseIntArrayElements(jbuffers, bufs, JNI_ABORT);
- }
- if(offsetsCopied) {
- env->ReleaseIntArrayElements(joffsets, offsets, JNI_ABORT);
- }
- if(lengthsCopied) {
- env->ReleaseIntArrayElements(jlengths, lengths, JNI_ABORT);
- }
- free(vectors);
- return totalRead;
+ delete[] vectors;
+ return result;
}
-/*
- * Class: org_apache_harmony_luni_platform_OSFileSystem
- * Method: transferImpl
- * Signature: (IJJ)J
- */
-static jlong harmony_io_transferImpl(JNIEnv *env, jobject thiz, jint fd,
- jobject sd, jlong offset, jlong count) {
+static jlong harmony_io_writev(JNIEnv* env, jobject, jint fd,
+ jintArray jBuffers, jintArray jOffsets, jintArray jLengths, jint size) {
+ iovec* vectors = initIoVec(env, jBuffers, jOffsets, jLengths, size);
+ if (vectors == NULL) {
+ return -1;
+ }
+ long result = writev(fd, vectors, size);
+ if (result == -1) {
+ jniThrowIOException(env, errno);
+ }
+ delete[] vectors;
+ return result;
+}
- int socket;
- off_t off;
+static jlong harmony_io_transfer(JNIEnv* env, jobject, jint fd, jobject sd,
+ jlong offset, jlong count) {
- socket = jniGetFDFromFileDescriptor(env, sd);
- if(socket == 0 || socket == -1) {
+ int socket = jniGetFDFromFileDescriptor(env, sd);
+ if (socket == -1) {
return -1;
}
/* Value of offset is checked in jint scope (checked in java layer)
The conversion here is to guarantee no value lost when converting offset to off_t
*/
- off = offset;
+ off_t off = offset;
- return sendfile(socket,(int)fd,(off_t *)&off,(size_t)count);
+ ssize_t rc = sendfile(socket, fd, &off, count);
+ if (rc == -1) {
+ jniThrowIOException(env, errno);
+ }
+ return rc;
}
-/*
- * Class: org_apache_harmony_io
- * Method: readDirectImpl
- * Signature: (IJI)J
- */
-static jlong harmony_io_readDirectImpl(JNIEnv * env, jobject thiz, jint fd,
+static jlong harmony_io_readDirect(JNIEnv* env, jobject, jint fd,
jint buf, jint offset, jint nbytes) {
- jint result;
- if(nbytes == 0) {
- return (jlong) 0;
+ if (nbytes == 0) {
+ return 0;
}
- result = read(fd, (void *) ((jint *)(buf+offset)), (int) nbytes);
- if(result == 0) {
- return (jlong) -1;
- } else {
- return (jlong) result;
+ jbyte* dst = reinterpret_cast<jbyte*>(buf + offset);
+ jlong rc = TEMP_FAILURE_RETRY(read(fd, dst, nbytes));
+ if (rc == 0) {
+ return -1;
}
+ if (rc == -1) {
+ jniThrowIOException(env, errno);
+ }
+ return rc;
}
-/*
- * Class: org_apache_harmony_io
- * Method: writeDirectImpl
- * Signature: (IJI)J
- */
-static jlong harmony_io_writeDirectImpl(JNIEnv * env, jobject thiz, jint fd,
+static jlong harmony_io_writeDirect(JNIEnv* env, jobject, jint fd,
jint buf, jint offset, jint nbytes) {
-
-
- int rc = 0;
-
- /* write will just do the right thing for HYPORT_TTY_OUT and HYPORT_TTY_ERR */
- rc = write (fd, (const void *) ((jint *)(buf+offset)), (int) nbytes);
-
- if(rc == -1) {
- jniThrowException(env, "java/io/IOException", strerror(errno));
- return -2;
+ jbyte* src = reinterpret_cast<jbyte*>(buf + offset);
+ jlong rc = TEMP_FAILURE_RETRY(write(fd, src, nbytes));
+ if (rc == -1) {
+ jniThrowIOException(env, errno);
}
- return (jlong) rc;
-
+ return rc;
}
-// BEGIN android-changed
-/*
- * Class: org_apache_harmony_io
- * Method: readImpl
- * Signature: (I[BII)J
- */
-static jlong harmony_io_readImpl(JNIEnv * env, jobject thiz, jint fd,
+static jlong harmony_io_readImpl(JNIEnv* env, jobject, jint fd,
jbyteArray byteArray, jint offset, jint nbytes) {
- jboolean isCopy;
- jbyte *bytes;
- jlong result;
-
if (nbytes == 0) {
return 0;
}
- bytes = env->GetByteArrayElements(byteArray, &isCopy);
-
- for (;;) {
- result = read(fd, (void *) (bytes + offset), (int) nbytes);
-
- if ((result != -1) || (errno != EINTR)) {
- break;
- }
-
- /*
- * If we didn't break above, that means that the read() call
- * returned due to EINTR. We shield Java code from this
- * possibility by trying again. Note that this is different
- * from EAGAIN, which should result in this code throwing
- * an InterruptedIOException.
- */
- }
-
+ jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
+ jlong rc = TEMP_FAILURE_RETRY(read(fd, bytes + offset, nbytes));
env->ReleaseByteArrayElements(byteArray, bytes, 0);
- if (result == 0) {
+ if (rc == 0) {
return -1;
}
-
- if (result == -1) {
+ if (rc == -1) {
if (errno == EAGAIN) {
jniThrowException(env, "java/io/InterruptedIOException",
"Read timed out");
} else {
- jniThrowException(env, "java/io/IOException", strerror(errno));
+ jniThrowIOException(env, errno);
}
}
-
- return result;
+ return rc;
}
-/*
- * Class: org_apache_harmony_io
- * Method: writeImpl
- * Signature: (I[BII)J
- */
-static jlong harmony_io_writeImpl(JNIEnv * env, jobject thiz, jint fd,
+static jlong harmony_io_writeImpl(JNIEnv* env, jobject, jint fd,
jbyteArray byteArray, jint offset, jint nbytes) {
- jboolean isCopy;
- jbyte *bytes = env->GetByteArrayElements(byteArray, &isCopy);
- jlong result;
-
- for (;;) {
- result = write(fd, (const char *) bytes + offset, (int) nbytes);
-
- if ((result != -1) || (errno != EINTR)) {
- break;
- }
-
- /*
- * If we didn't break above, that means that the read() call
- * returned due to EINTR. We shield Java code from this
- * possibility by trying again. Note that this is different
- * from EAGAIN, which should result in this code throwing
- * an InterruptedIOException.
- */
- }
-
+ jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
+ jlong result = TEMP_FAILURE_RETRY(write(fd, bytes + offset, nbytes));
env->ReleaseByteArrayElements(byteArray, bytes, JNI_ABORT);
if (result == -1) {
@@ -416,157 +342,77 @@
jniThrowException(env, "java/io/InterruptedIOException",
"Write timed out");
} else {
- jniThrowException(env, "java/io/IOException", strerror(errno));
+ jniThrowIOException(env, errno);
}
}
-
return result;
}
-// END android-changed
-/**
- * Seeks a file descriptor to a given file position.
- *
- * @param env pointer to Java environment
- * @param thiz pointer to object receiving the message
- * @param fd handle of file to be seeked
- * @param offset distance of movement in bytes relative to whence arg
- * @param whence enum value indicating from where the offset is relative
- * The valid values are defined in fsconstants.h.
- * @return the new file position from the beginning of the file, in bytes;
- * or -1 if a problem occurs.
- */
-static jlong harmony_io_seekImpl(JNIEnv * env, jobject thiz, jint fd,
- jlong offset, jint whence) {
-
- int mywhence = 0;
-
+static jlong harmony_io_seek(JNIEnv* env, jobject, jint fd, jlong offset,
+ jint javaWhence) {
/* Convert whence argument */
- switch (whence) {
- case 1:
- mywhence = 0;
- break;
- case 2:
- mywhence = 1;
- break;
- case 4:
- mywhence = 2;
- break;
- default:
- return -1;
- }
-
-
- off_t localOffset = (int) offset;
-
- if((mywhence < 0) || (mywhence > 2)) {
+ int nativeWhence = 0;
+ switch (javaWhence) {
+ case 1:
+ nativeWhence = SEEK_SET;
+ break;
+ case 2:
+ nativeWhence = SEEK_CUR;
+ break;
+ case 4:
+ nativeWhence = SEEK_END;
+ break;
+ default:
return -1;
}
- /* If file offsets are 32 bit, truncate the seek to that range */
- if(sizeof (off_t) < sizeof (jlong)) {
- if(offset > 0x7FFFFFFF) {
- localOffset = 0x7FFFFFFF;
- } else if(offset < -0x7FFFFFFF) {
- localOffset = -0x7FFFFFFF;
- }
+ // If the offset is relative, lseek(2) will tell us whether it's too large.
+ // We're just worried about too large an absolute offset, which would cause
+ // us to lie to lseek(2).
+ if (offsetTooLarge(env, offset)) {
+ return -1;
}
- return (jlong) lseek(fd, localOffset, mywhence);
-}
-
-/**
- * Flushes a file state to disk.
- *
- * @param env pointer to Java environment
- * @param thiz pointer to object receiving the message
- * @param fd handle of file to be flushed
- * @param metadata if true also flush metadata,
- * otherwise just flush data is possible.
- * @return zero on success and -1 on failure
- *
- * Method: fflushImpl
- * Signature: (IZ)I
- */
-static jint harmony_io_fflushImpl(JNIEnv * env, jobject thiz, jint fd,
- jboolean metadata) {
- return (jint) fsync(fd);
-}
-
-// BEGIN android-changed
-/**
- * Closes the given file handle
- *
- * @param env pointer to Java environment
- * @param thiz pointer to object receiving the message
- * @param fd handle of file to be closed
- * @return zero on success and -1 on failure
- *
- * Class: org_apache_harmony_io
- * Method: closeImpl
- * Signature: (I)I
- */
-static jint harmony_io_closeImpl(JNIEnv * env, jobject thiz, jint fd) {
- jint result;
-
- for (;;) {
- result = (jint) close(fd);
-
- if ((result != -1) || (errno != EINTR)) {
- break;
- }
-
- /*
- * If we didn't break above, that means that the close() call
- * returned due to EINTR. We shield Java code from this
- * possibility by trying again.
- */
+ jlong result = lseek(fd, offset, nativeWhence);
+ if (result == -1) {
+ jniThrowIOException(env, errno);
}
-
return result;
}
-// END android-changed
-
-/*
- * Class: org_apache_harmony_io
- * Method: truncateImpl
- * Signature: (IJ)I
- */
-static jint harmony_io_truncateImpl(JNIEnv * env, jobject thiz, jint fd,
- jlong size) {
-
- int rc;
- off_t length = (off_t) size;
-
- // If file offsets are 32 bit, truncate the newLength to that range
- if(sizeof (off_t) < sizeof (jlong)) {
- if(length > 0x7FFFFFFF) {
- length = 0x7FFFFFFF;
- } else if(length < -0x7FFFFFFF) {
- length = -0x7FFFFFFF;
- }
+// TODO: are we supposed to support the 'metadata' flag? (false => fdatasync.)
+static void harmony_io_fflush(JNIEnv* env, jobject, jint fd,
+ jboolean metadata) {
+ int rc = fsync(fd);
+ if (rc == -1) {
+ jniThrowIOException(env, errno);
}
-
- rc = ftruncate((int)fd, length);
-
- return (jint) rc;
-
}
-/*
- * Class: org_apache_harmony_io
- * Method: openImpl
- * Signature: ([BI)I
- */
-static jint harmony_io_openImpl(JNIEnv * env, jobject obj, jbyteArray path,
+static jint harmony_io_close(JNIEnv* env, jobject, jint fd) {
+ jint rc = TEMP_FAILURE_RETRY(close(fd));
+ if (rc == -1) {
+ jniThrowIOException(env, errno);
+ }
+ return rc;
+}
+
+static jint harmony_io_truncate(JNIEnv* env, jobject, jint fd, jlong length) {
+ if (offsetTooLarge(env, length)) {
+ return -1;
+ }
+
+ int rc = ftruncate(fd, length);
+ if (rc == -1) {
+ jniThrowIOException(env, errno);
+ }
+ return rc;
+}
+
+static jint harmony_io_openImpl(JNIEnv* env, jobject, jbyteArray path,
jint jflags) {
-
int flags = 0;
- int mode = 0;
- jint * portFD;
- jsize length;
- char pathCopy[HyMaxPath];
+ int mode = 0;
// BEGIN android-changed
// don't want default permissions to allow global access.
@@ -588,7 +434,7 @@
mode = 0600;
break;
case 256:
- flags = HyOpenWrite | HyOpenCreate | HyOpenAppend;
+ flags = HyOpenWrite | HyOpenCreate | HyOpenAppend;
mode = 0600;
break;
}
@@ -596,116 +442,56 @@
flags = EsTranslateOpenFlags(flags);
- length = env->GetArrayLength (path);
+ // TODO: clean this up when we clean up the java.io.File equivalent.
+ jsize length = env->GetArrayLength (path);
length = length < HyMaxPath - 1 ? length : HyMaxPath - 1;
+ char pathCopy[HyMaxPath];
env->GetByteArrayRegion (path, 0, length, (jbyte *)pathCopy);
pathCopy[length] = '\0';
convertToPlatform (pathCopy);
- int cc;
-
- if(pathCopy == NULL) {
- jniThrowException(env, "java/lang/NullPointerException", NULL);
- return -1;
- }
-
- do {
- cc = open(pathCopy, flags, mode);
- } while(cc < 0 && errno == EINTR);
-
- if(cc < 0 && errno > 0) {
+ jint cc = TEMP_FAILURE_RETRY(open(pathCopy, flags, mode));
+ // TODO: chase up the callers of this and check they wouldn't rather
+ // have us throw a meaningful IOException right here.
+ if (cc < 0 && errno > 0) {
cc = -errno;
}
-
return cc;
-
-
}
-// BEGIN android-deleted
-#if 0
-/*
- * Answers the number of remaining chars in the stdin.
- *
- * Class: org_apache_harmony_io
- * Method: ttyAvailableImpl
- * Signature: ()J
- */
-static jlong harmony_io_ttyAvailableImpl(JNIEnv *env, jobject thiz) {
-
- int rc;
- off_t curr, end;
-
- int avail = 0;
-
- // when redirected from a file
- curr = lseek(STDIN_FILENO, 0L, 2); /* don't use tell(), it doesn't exist on all platforms, i.e. linux */
- if(curr != -1) {
- end = lseek(STDIN_FILENO, 0L, 4);
- lseek(STDIN_FILENO, curr, 1);
- if(end >= curr) {
- return (jlong) (end - curr);
- }
- }
-
- /* ioctl doesn't work for files on all platforms (i.e. SOLARIS) */
-
- rc = ioctl (STDIN_FILENO, FIONREAD, &avail);
-
- /* 64 bit platforms use a 32 bit value, using IDATA fails on big endian */
- /* Pass in IDATA because ioctl() is device dependent, some devices may write 64 bits */
- if(rc != -1) {
- return (jlong) *(jint *) & avail;
- }
- return (jlong) 0;
-}
-#endif
-// END android-deleted
-
-// BEGIN android-added
-/*
- * Answers the number of remaining bytes in a file descriptor
- * using IOCTL.
- *
- * Class: org_apache_harmony_io
- * Method: ioctlAvailable
- * Signature: ()I
- */
-static jint harmony_io_ioctlAvailable(JNIEnv *env, jobject thiz, jint fd) {
- int avail = 0;
- int rc = ioctl(fd, FIONREAD, &avail);
-
+static jint harmony_io_ioctlAvailable(JNIEnv*env, jobject, jint fd) {
/*
* On underlying platforms Android cares about (read "Linux"),
* ioctl(fd, FIONREAD, &avail) is supposed to do the following:
- *
+ *
* If the fd refers to a regular file, avail is set to
* the difference between the file size and the current cursor.
* This may be negative if the cursor is past the end of the file.
- *
+ *
* If the fd refers to an open socket or the read end of a
* pipe, then avail will be set to a number of bytes that are
* available to be read without blocking.
- *
+ *
* If the fd refers to a special file/device that has some concept
* of buffering, then avail will be set in a corresponding way.
- *
+ *
* If the fd refers to a special device that does not have any
* concept of buffering, then the ioctl call will return a negative
* number, and errno will be set to ENOTTY.
- *
+ *
* If the fd refers to a special file masquerading as a regular file,
* then avail may be returned as negative, in that the special file
* may appear to have zero size and yet a previous read call may have
* actually read some amount of data and caused the cursor to be
* advanced.
*/
-
+ int avail = 0;
+ int rc = ioctl(fd, FIONREAD, &avail);
if (rc >= 0) {
/*
* Success, but make sure not to return a negative number (see
* above).
- */
+ */
if (avail < 0) {
avail = 0;
}
@@ -714,94 +500,37 @@
avail = 0;
} else {
/* Something strange is happening. */
- jniThrowException(env, "java/io/IOException", strerror(errno));
- avail = 0;
- }
+ jniThrowIOException(env, errno);
+ }
return (jint) avail;
}
-// END android-added
-
-/*
- * Reads the number of bytes from stdin.
- *
- * Class: org_apache_harmony_io
- * Method: ttyReadImpl
- * Signature: ([BII)J
- */
-static jlong harmony_io_ttyReadImpl(JNIEnv *env, jobject thiz,
- jbyteArray byteArray, jint offset, jint nbytes) {
-
- jboolean isCopy;
- jbyte *bytes = env->GetByteArrayElements(byteArray, &isCopy);
- jlong result;
-
- for(;;) {
-
- result = (jlong) read(STDIN_FILENO, (char *)(bytes + offset), (int) nbytes);
-
- if ((result != -1) || (errno != EINTR)) {
- break;
- }
-
- /*
- * If we didn't break above, that means that the read() call
- * returned due to EINTR. We shield Java code from this
- * possibility by trying again. Note that this is different
- * from EAGAIN, which should result in this code throwing
- * an InterruptedIOException.
- */
- }
-
- env->ReleaseByteArrayElements(byteArray, bytes, 0);
-
- if (result == 0) {
- return -1;
- }
-
- if (result == -1) {
- if (errno == EAGAIN) {
- jniThrowException(env, "java/io/InterruptedIOException",
- "Read timed out");
- } else {
- jniThrowException(env, "java/io/IOException", strerror(errno));
- }
- }
-
- return result;
-}
/*
* JNI registration
*/
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
- { "lockImpl", "(IJJIZ)I", (void*) harmony_io_lockImpl },
- { "getAllocGranularity","()I", (void*) harmony_io_getAllocGranularity },
- { "unlockImpl", "(IJJ)I", (void*) harmony_io_unlockImpl },
- { "fflushImpl", "(IZ)I", (void*) harmony_io_fflushImpl },
- { "seekImpl", "(IJI)J", (void*) harmony_io_seekImpl },
- { "readDirectImpl", "(IIII)J", (void*) harmony_io_readDirectImpl },
- { "writeDirectImpl", "(IIII)J", (void*) harmony_io_writeDirectImpl },
- { "readImpl", "(I[BII)J", (void*) harmony_io_readImpl },
- { "writeImpl", "(I[BII)J", (void*) harmony_io_writeImpl },
- { "readvImpl", "(I[I[I[II)J",(void*) harmony_io_readvImpl },
- { "writevImpl", "(I[I[I[II)J",(void*) harmony_io_writevImpl },
- { "closeImpl", "(I)I", (void*) harmony_io_closeImpl },
- { "truncateImpl", "(IJ)I", (void*) harmony_io_truncateImpl },
- { "openImpl", "([BI)I", (void*) harmony_io_openImpl },
- { "transferImpl", "(ILjava/io/FileDescriptor;JJ)J",
- (void*) harmony_io_transferImpl },
- // BEGIN android-deleted
- //{ "ttyAvailableImpl", "()J", (void*) harmony_io_ttyAvailableImpl },
- // END android-deleted
- // BEGIN android-added
+ { "close", "(I)V", (void*) harmony_io_close },
+ { "fflush", "(IZ)V", (void*) harmony_io_fflush },
+ { "getAllocGranularity","()I", (void*) harmony_io_getAllocGranularity },
{ "ioctlAvailable", "(I)I", (void*) harmony_io_ioctlAvailable },
- // END android added
- { "ttyReadImpl", "([BII)J", (void*) harmony_io_ttyReadImpl }
+ { "lockImpl", "(IJJIZ)I", (void*) harmony_io_lockImpl },
+ { "openImpl", "([BI)I", (void*) harmony_io_openImpl },
+ { "readDirect", "(IIII)J", (void*) harmony_io_readDirect },
+ { "readImpl", "(I[BII)J", (void*) harmony_io_readImpl },
+ { "readv", "(I[I[I[II)J",(void*) harmony_io_readv },
+ { "seek", "(IJI)J", (void*) harmony_io_seek },
+ { "transfer", "(ILjava/io/FileDescriptor;JJ)J",
+ (void*) harmony_io_transfer },
+ { "truncate", "(IJ)V", (void*) harmony_io_truncate },
+ { "unlockImpl", "(IJJ)V", (void*) harmony_io_unlockImpl },
+ { "writeDirect", "(IIII)J", (void*) harmony_io_writeDirect },
+ { "writeImpl", "(I[BII)J", (void*) harmony_io_writeImpl },
+ { "writev", "(I[I[I[II)J",(void*) harmony_io_writev },
};
-int register_org_apache_harmony_luni_platform_OSFileSystem(JNIEnv *_env) {
- return jniRegisterNativeMethods(_env,
- "org/apache/harmony/luni/platform/OSFileSystem", gMethods,
- NELEM(gMethods));
+int register_org_apache_harmony_luni_platform_OSFileSystem(JNIEnv* _env) {
+ return jniRegisterNativeMethods(_env,
+ "org/apache/harmony/luni/platform/OSFileSystem", gMethods,
+ NELEM(gMethods));
}
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp
index 2e814cc..1d63faf 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp
@@ -34,12 +34,9 @@
jobject runtimeInstance;
} gIDCache;
-#undef MMAP_READ_ONLY
-#define MMAP_READ_ONLY 1L
-#undef MMAP_READ_WRITE
-#define MMAP_READ_WRITE 2L
-#undef MMAP_WRITE_COPY
-#define MMAP_WRITE_COPY 4L
+static const int MMAP_READ_ONLY = 1;
+static const int MMAP_READ_WRITE = 2;
+static const int MMAP_WRITE_COPY = 4;
/*
* Class: org_apache_harmony_luni_platform_OSMemory
@@ -144,9 +141,8 @@
*/
static void harmony_nio_getBytesImpl(JNIEnv *_env, jobject _this, jint pointer,
jbyteArray dst, jint offset, jint length) {
- jbyte *dst_ = (jbyte *)_env->GetPrimitiveArrayCritical(dst, (jboolean *)0);
- memcpy(dst_ + offset, (jbyte *)pointer, length);
- _env->ReleasePrimitiveArrayCritical(dst, dst_, 0);
+ jbyte* src = reinterpret_cast<jbyte*>(static_cast<uintptr_t>(pointer));
+ _env->SetByteArrayRegion(dst, offset, length, src);
}
/*
@@ -166,9 +162,8 @@
*/
static void harmony_nio_putBytesImpl(JNIEnv *_env, jobject _this,
jint pointer, jbyteArray src, jint offset, jint length) {
- jbyte *src_ = (jbyte *)_env->GetPrimitiveArrayCritical(src, (jboolean *)0);
- memcpy((jbyte *)pointer, src_ + offset, length);
- _env->ReleasePrimitiveArrayCritical(src, src_, JNI_ABORT);
+ jbyte* dst = reinterpret_cast<jbyte*>(static_cast<uintptr_t>(pointer));
+ _env->GetByteArrayRegion(src, offset, length, dst);
}
static void
@@ -431,36 +426,33 @@
* Method: mmapImpl
* Signature: (IJJI)I
*/
-static jint harmony_nio_mmapImpl(JNIEnv *_env, jobject _this, jint fd,
- jlong alignment, jlong size, jint mmode) {
- void *mapAddress = NULL;
+static jint harmony_nio_mmapImpl(JNIEnv* env, jobject, jint fd,
+ jlong offset, jlong size, jint mapMode) {
int prot, flags;
-
- // Convert from Java mapping mode to port library mapping mode.
- switch (mmode) {
- case MMAP_READ_ONLY:
- prot = PROT_READ;
- flags = MAP_SHARED;
- break;
- case MMAP_READ_WRITE:
- prot = PROT_READ|PROT_WRITE;
- flags = MAP_SHARED;
- break;
- case MMAP_WRITE_COPY:
- prot = PROT_READ|PROT_WRITE;
- flags = MAP_PRIVATE;
- break;
- default:
- return -1;
- }
-
- mapAddress = mmap(0, (size_t)(size&0x7fffffff), prot, flags,fd,
- (off_t)(alignment&0x7fffffff));
- if (mapAddress == MAP_FAILED) {
+ switch (mapMode) {
+ case MMAP_READ_ONLY:
+ prot = PROT_READ;
+ flags = MAP_SHARED;
+ break;
+ case MMAP_READ_WRITE:
+ prot = PROT_READ|PROT_WRITE;
+ flags = MAP_SHARED;
+ break;
+ case MMAP_WRITE_COPY:
+ prot = PROT_READ|PROT_WRITE;
+ flags = MAP_PRIVATE;
+ break;
+ default:
+ jniThrowIOException(env, EINVAL);
+ LOGE("bad mapMode %i", mapMode);
return -1;
}
-
- return (jint) mapAddress;
+
+ void* mapAddress = mmap(0, size, prot, flags, fd, offset);
+ if (mapAddress == MAP_FAILED) {
+ jniThrowIOException(env, errno);
+ }
+ return reinterpret_cast<uintptr_t>(mapAddress);
}
/*
@@ -496,15 +488,6 @@
return -1;
}
-int getPageSize() {
- static int page_size = 0;
- if(page_size==0)
- {
- page_size=getpagesize();
- }
- return page_size;
-}
-
/*
* Class: org_apache_harmony_luni_platform_OSMemory
* Method: isLoadedImpl
@@ -513,18 +496,16 @@
static jboolean harmony_nio_isLoadedImpl(JNIEnv *_env, jobject _this,
jint address, jlong size) {
+ static int page_size = getpagesize();
jboolean result = 0;
jint m_addr = (jint)address;
- int page_size = getPageSize();
- unsigned char* vec = NULL;
- int page_count = 0;
int align_offset = m_addr%page_size;// addr should align with the boundary of a page.
m_addr -= align_offset;
size += align_offset;
- page_count = (size+page_size-1)/page_size;
+ int page_count = (size+page_size-1)/page_size;
- vec = (unsigned char *) malloc(page_count*sizeof(char));
+ unsigned char* vec = (unsigned char *) malloc(page_count*sizeof(char));
if (mincore((void *)m_addr, size, (MINCORE_POINTER_TYPE) vec)==0) {
// or else there is error about the mincore and return false;
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index 635e1af..af2e08a 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -23,29 +23,40 @@
#define LOG_TAG "OSNetworkSystem"
+#include "AndroidSystemNatives.h"
#include "JNIHelp.h"
#include "jni.h"
-#include "errno.h"
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/time.h>
#include <sys/un.h>
-
-#include <cutils/properties.h>
-#include <cutils/adb_networking.h>
-#include "AndroidSystemNatives.h"
+#include <unistd.h>
// Temporary hack to build on systems that don't have up-to-date libc headers.
#ifndef IPV6_TCLASS
-#define IPV6_TCLASS 67
+#ifdef __linux__
+#define IPV6_TCLASS 67 // Linux
+#else
+#define IPV6_TCLASS -1 // BSD(-like); TODO: Something better than this!
+#endif
+#endif
+
+/*
+ * TODO: The multicast code is highly platform-dependent, and for now
+ * we just punt on anything but Linux.
+ */
+#ifdef __linux__
+#define ENABLE_MULTICAST
#endif
/**
@@ -54,7 +65,6 @@
*
* @internal SOCKERR* range from -200 to -299 avoid overlap
*/
-#define SOCKERR_BADSOCKET -200 /* generic error */
#define SOCKERR_NOTINITIALIZED -201 /* socket library uninitialized */
#define SOCKERR_BADAF -202 /* bad address family */
#define SOCKERR_BADPROTO -203 /* bad protocol */
@@ -69,7 +79,6 @@
#define SOCKERR_ADDRNOTAVAIL -212 /* address not available */
#define SOCKERR_ADDRINUSE -213 /* address already in use */
#define SOCKERR_NOTBOUND -214 /* the socket is not bound */
-#define SOCKERR_UNKNOWNSOCKET -215 /* resolution of fileDescriptor to socket failed */
#define SOCKERR_INVALIDTIMEOUT -216 /* the specified timeout is invalid */
#define SOCKERR_FDSETFULL -217 /* Unable to create an FDSET */
#define SOCKERR_TIMEVALFULL -218 /* Unable to create a TIMEVAL */
@@ -113,9 +122,7 @@
#define JAVASOCKOPT_IP_TOS 3
#define JAVASOCKOPT_SO_REUSEADDR 4
#define JAVASOCKOPT_SO_KEEPALIVE 8
-#define JAVASOCKOPT_MCAST_TIME_TO_LIVE 10 /* Currently unused */
-#define JAVASOCKOPT_SO_BINDADDR 15
-#define JAVASOCKOPT_MCAST_INTERFACE 16
+#define JAVASOCKOPT_IP_MULTICAST_IF 16
#define JAVASOCKOPT_MCAST_TTL 17
#define JAVASOCKOPT_IP_MULTICAST_LOOP 18
#define JAVASOCKOPT_MCAST_ADD_MEMBERSHIP 19
@@ -144,19 +151,9 @@
#define SOCKET_OP_NONE 0
#define SOCKET_OP_READ 1
#define SOCKET_OP_WRITE 2
-#define SOCKET_READ_WRITE 3
-
-#define SOCKET_MSG_PEEK 1
-#define SOCKET_MSG_OOB 2
#define SOCKET_NOFLAGS 0
-#undef BUFFERSIZE
-#define BUFFERSIZE 2048
-
-// wait for 500000 usec = 0.5 second
-#define SEND_RETRY_TIME 500000
-
// Local constants for getOrSetSocketOption
#define SOCKOPT_GET 1
#define SOCKOPT_SET 2
@@ -178,8 +175,6 @@
jclass byte_class;
jmethodID byte_class_init;
jfieldID byte_class_value;
- jclass string_class;
- jmethodID string_class_init;
jclass socketimpl_class;
jfieldID socketimpl_address;
jfieldID socketimpl_port;
@@ -189,50 +184,72 @@
jfieldID dpack_length;
} gCachedFields;
-static int useAdbNetworking = 0;
-
/* needed for connecting with timeout */
-typedef struct selectFDSet {
+struct selectFDSet {
int nfds;
int sock;
fd_set writeSet;
fd_set readSet;
fd_set exceptionSet;
-} selectFDSet;
+};
static const char * netLookupErrorString(int anErrorNum);
/**
* Throws an SocketException with the message affiliated with the errorCode.
+ *
+ * @deprecated: 'errorCode' is one of the bogus SOCKERR_ values, *not* errno.
+ * jniThrowSocketException is the better choice.
*/
static void throwSocketException(JNIEnv *env, int errorCode) {
jniThrowException(env, "java/net/SocketException",
netLookupErrorString(errorCode));
}
-/**
- * Throws an IOException with the given message.
- */
-static void throwIOExceptionStr(JNIEnv *env, const char *message) {
- jniThrowException(env, "java/io/IOException", message);
+// TODO(enh): move to JNIHelp.h
+static void jniThrowExceptionWithErrno(JNIEnv* env,
+ const char* exceptionClassName, int error) {
+ char buf[BUFSIZ];
+ jniThrowException(env, exceptionClassName,
+ jniStrError(error, buf, sizeof(buf)));
}
-/**
- * Throws a NullPointerException.
- */
+static void jniThrowBindException(JNIEnv* env, int error) {
+ jniThrowExceptionWithErrno(env, "java/net/BindException", error);
+}
+
+static void jniThrowSocketException(JNIEnv* env, int error) {
+ jniThrowExceptionWithErrno(env, "java/net/SocketException", error);
+}
+
+static void jniThrowSocketTimeoutException(JNIEnv* env, int error) {
+ jniThrowExceptionWithErrno(env, "java/net/SocketTimeoutException", error);
+}
+
+// TODO(enh): move to JNIHelp.h
static void throwNullPointerException(JNIEnv *env) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
}
+// Used by functions that shouldn't throw SocketException. (These functions
+// aren't meant to see bad addresses, so seeing one really does imply an
+// internal error.)
+// TODO: fix the code (native and Java) so we don't paint ourselves into this corner.
+static void jniThrowBadAddressFamily(JNIEnv* env) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "Bad address family");
+}
+
+static bool jniGetFd(JNIEnv* env, jobject fileDescriptor, int& fd) {
+ fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (fd == -1) {
+ jniThrowSocketException(env, EBADF);
+ return false;
+ }
+ return true;
+}
+
/**
- * Converts a native address structure to a Java byte array. Throws a
- * NullPointerException or an IOException in case of error. This is
- * signaled by a return value of -1. The normal return value is 0.
- *
- * @param address the sockaddr_storage structure to convert
- *
- * @exception SocketException the address family is unknown, or out of memory
- *
+ * Converts a native address structure to a Java byte array.
*/
static jbyteArray socketAddressToByteArray(JNIEnv *env,
struct sockaddr_storage *address) {
@@ -248,13 +265,12 @@
rawAddress = &sin6->sin6_addr.s6_addr;
addressLength = 16;
} else {
- throwSocketException(env, SOCKERR_BADAF);
+ jniThrowBadAddressFamily(env);
return NULL;
}
jbyteArray byteArray = env->NewByteArray(addressLength);
if (byteArray == NULL) {
- throwSocketException(env, SOCKERR_NOBUFFERS);
return NULL;
}
env->SetByteArrayRegion(byteArray, 0, addressLength, (jbyte *) rawAddress);
@@ -281,208 +297,124 @@
}
/**
- * Checks whether a socket address structure contains an IPv4-mapped address.
- *
- * @param address the socket address structure to check
- * @return true if address contains an IPv4-mapped address, false otherwise.
+ * Obtain the socket address family from an existing socket.
+ *
+ * @param socket the file descriptor of the socket to examine
+ * @return an integer, the address family of the socket
*/
-static bool isMappedAddress(sockaddr *address) {
- if (! address || address->sa_family != AF_INET6) {
- return false;
+static int getSocketAddressFamily(int socket) {
+ sockaddr_storage ss;
+ socklen_t namelen = sizeof(ss);
+ int ret = getsockname(socket, (sockaddr*) &ss, &namelen);
+ if (ret != 0) {
+ return AF_UNSPEC;
+ } else {
+ return ss.ss_family;
}
- in6_addr addr = ((sockaddr_in6 *) address)->sin6_addr;
- return (addr.s6_addr32[0] == 0 &&
- addr.s6_addr32[1] == 0 &&
- addr.s6_addr32[2] == htonl(0xffff));
}
-/**
- * Checks whether a 16-byte array represents an IPv4-mapped IPv6 address.
- *
- * @param addressBytes the address to check. Must be 16 bytes long.
- * @return true if address contains an IPv4-mapped address, false otherwise.
- */
-static bool isJavaMappedAddress(jbyte *addressBytes) {
- static const unsigned char mappedBytes[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
- return !memcmp(mappedBytes, addressBytes, sizeof(mappedBytes));
-}
-
-/**
- * Converts a native address structure to an InetAddress object.
- * Throws a NullPointerException or an IOException in case of
- * error. This is signaled by a return value of -1. The normal
- * return value is 0.
- *
- * @param sockaddress the sockaddr_storage structure to convert
- *
- * @return a jobject representing an InetAddress
- */
-static jobject socketAddressToInetAddress(JNIEnv *env,
- struct sockaddr_storage *sockaddress) {
-
- jbyteArray byteArray = socketAddressToByteArray(env, sockaddress);
- if (byteArray == NULL) // Exception has already been thrown.
+jobject byteArrayToInetAddress(JNIEnv* env, jbyteArray byteArray) {
+ if (byteArray == NULL) {
return NULL;
-
+ }
return env->CallStaticObjectMethod(gCachedFields.iaddr_class,
gCachedFields.iaddr_getbyaddress, byteArray);
}
/**
- * Converts an IPv4-mapped IPv6 address to an IPv4 address. Performs no error
- * checking.
+ * Converts a native address structure to an InetAddress object.
+ * Throws a NullPointerException or an IOException in case of
+ * error.
*
- * @param address the address to convert. Must contain an IPv4-mapped address.
- * @param outputAddress the converted address. Will contain an IPv4 address.
+ * @param sockAddress the sockaddr_storage structure to convert
+ *
+ * @return a jobject representing an InetAddress
*/
-static void convertMappedToIpv4(sockaddr_in6 *sin6, sockaddr_in *sin) {
- memset(sin, 0, sizeof(*sin));
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
- sin->sin_port = sin6->sin6_port;
+jobject socketAddressToInetAddress(JNIEnv* env, sockaddr_storage* sockAddress) {
+ jbyteArray byteArray = socketAddressToByteArray(env, sockAddress);
+ return byteArrayToInetAddress(env, byteArray);
}
/**
- * Converts an IPv4 address to an IPv4-mapped IPv6 address. Performs no error
- * checking.
- *
- * @param address the address to convert. Must contain an IPv4 address.
- * @param outputAddress the converted address. Will contain an IPv6 address.
+ * Converts an IPv4 address to an IPv4-mapped IPv6 address if fd is an IPv6
+ * socket.
+ * @param fd the socket.
+ * @param sin_ss the address.
+ * @param sin6_ss scratch space where we can store the mapped address if necessary.
* @param mapUnspecified if true, convert 0.0.0.0 to ::ffff:0:0; if false, to ::
+ * @return either sin_ss or sin6_ss, depending on which the caller should use.
*/
-static void convertIpv4ToMapped(struct sockaddr_in *sin,
- struct sockaddr_in6 *sin6, bool mapUnspecified) {
- memset(sin6, 0, sizeof(*sin6));
- sin6->sin6_family = AF_INET6;
- sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
- if (sin->sin_addr.s_addr != 0 || mapUnspecified) {
- sin6->sin6_addr.s6_addr32[2] = htonl(0xffff);
- }
- sin6->sin6_port = sin->sin_port;
+static const sockaddr* convertIpv4ToMapped(int fd,
+ const sockaddr_storage* sin_ss, sockaddr_storage* sin6_ss, bool mapUnspecified) {
+ // We need to map if we have an IPv4 address but an IPv6 socket.
+ bool needsMapping = (sin_ss->ss_family == AF_INET && getSocketAddressFamily(fd) == AF_INET6);
+ if (!needsMapping) {
+ return reinterpret_cast<const sockaddr*>(sin_ss);
+ }
+ // Map the IPv4 address in sin_ss into an IPv6 address in sin6_ss.
+ const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(sin_ss);
+ sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(sin6_ss);
+ memset(sin6, 0, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_port = sin->sin_port;
+ if (sin->sin_addr.s_addr != 0 || mapUnspecified) {
+ memset(&(sin6->sin6_addr.s6_addr[10]), 0xff, 2);
+ }
+ memcpy(&sin6->sin6_addr.s6_addr[12], &sin->sin_addr.s_addr, 4);
+ return reinterpret_cast<const sockaddr*>(sin6_ss);
}
/**
* Converts an InetAddress object and port number to a native address structure.
* Throws a NullPointerException or a SocketException in case of
- * error. This is signaled by a return value of -1. The normal
- * return value is 0.
- *
- * @param inetaddress the InetAddress object to convert
- * @param port the port number
- * @param sockaddress the sockaddr_storage structure to write to
- *
- * @return 0 on success, a system error code on failure
- *
- * @exception SocketError if the address family is unknown
+ * error.
*/
-static int byteArrayToSocketAddress(JNIEnv *env,
- jbyteArray addressByteArray, int port, sockaddr_storage *sockaddress) {
- if (addressByteArray == NULL) {
- throwNullPointerException(env);
- return EFAULT;
+static bool byteArrayToSocketAddress(JNIEnv *env,
+ jbyteArray addressBytes, int port, sockaddr_storage *sockaddress) {
+ if (addressBytes == NULL) {
+ throwNullPointerException(env);
+ return false;
}
- size_t addressLength = env->GetArrayLength(addressByteArray);
// Convert the IP address bytes to the proper IP address type.
+ size_t addressLength = env->GetArrayLength(addressBytes);
+ memset(sockaddress, 0, sizeof(*sockaddress));
if (addressLength == 4) {
// IPv4 address.
- sockaddr_in *sin = (sockaddr_in *) sockaddress;
- memset(sin, 0, sizeof(sockaddr_in));
+ sockaddr_in *sin = reinterpret_cast<sockaddr_in*>(sockaddress);
sin->sin_family = AF_INET;
sin->sin_port = htons(port);
- jbyte *rawBytes = (jbyte *) &sin->sin_addr.s_addr;
- env->GetByteArrayRegion(addressByteArray, 0, 4, rawBytes);
+ jbyte* dst = reinterpret_cast<jbyte*>(&sin->sin_addr.s_addr);
+ env->GetByteArrayRegion(addressBytes, 0, 4, dst);
} else if (addressLength == 16) {
// IPv6 address.
- sockaddr_in6 *sin6 = (sockaddr_in6 *) sockaddress;
- memset(sin6, 0, sizeof(sockaddr_in6));
+ sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6*>(sockaddress);
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons(port);
- jbyte *rawBytes = (jbyte *) &sin6->sin6_addr.s6_addr;
- env->GetByteArrayRegion(addressByteArray, 0, 16, rawBytes);
+ jbyte* dst = reinterpret_cast<jbyte*>(&sin6->sin6_addr.s6_addr);
+ env->GetByteArrayRegion(addressBytes, 0, 16, dst);
} else {
- // Unknown address family.
- throwSocketException(env, SOCKERR_BADAF);
- return EAFNOSUPPORT;
+ jniThrowBadAddressFamily(env);
+ return false;
}
- return 0;
+ return true;
}
/**
* Converts an InetAddress object and port number to a native address structure.
- * Throws a NullPointerException or a SocketException in case of
- * error. This is signaled by a return value of -1. The normal
- * return value is 0.
- *
- * @param inetaddress the InetAddress object to convert
- * @param port the port number
- * @param sockaddress the sockaddr_storage structure to write to
- *
- * @return 0 on success, -1 on failure
- * @throw UnknownHostException if any error occurs
- *
- * @exception SocketError if the address family is unknown
*/
-static int inetAddressToSocketAddress(JNIEnv *env,
- jobject inetaddress, int port, sockaddr_storage *sockaddress) {
-
+static bool inetAddressToSocketAddress(JNIEnv *env, jobject inetaddress,
+ int port, sockaddr_storage *sockaddress) {
// Get the byte array that stores the IP address bytes in the InetAddress.
- jbyteArray addressByteArray;
- addressByteArray = (jbyteArray)env->GetObjectField(inetaddress,
- gCachedFields.iaddr_ipaddress);
-
- return byteArrayToSocketAddress(env, addressByteArray, port, sockaddress);
-}
-
-/**
- * Convert a sockaddr_storage structure to a Java string.
- *
- * @param address pointer to sockaddr_storage structure to convert.
- * @param withPort whether to include the port number in the output as well.
- *
- * @return 0 on success, a getnameinfo return code on failure.
- *
- * @throws SocketException the address family was unknown.
- */
-static int socketAddressToString(sockaddr_storage *address, char *ipString,
- int len, bool withPort) {
- // TODO: getnameinfo seems to want its length parameter to be exactly
- // sizeof(sockaddr_in) for an IPv4 address and sizeof (sockaddr_in6) for an
- // IPv6 address. Fix getnameinfo so it accepts sizeof(sockaddr_storage), and
- // then remove this hack.
- int size;
- if (address->ss_family == AF_INET) {
- size = sizeof(sockaddr_in);
- } else if (address->ss_family == AF_INET6) {
- size = sizeof(sockaddr_in6);
- } else {
- errno = EAFNOSUPPORT;
- return EAI_SYSTEM;
+ if (inetaddress == NULL) {
+ throwNullPointerException(env);
+ return false;
}
+ jbyteArray addressBytes =
+ reinterpret_cast<jbyteArray>(env->GetObjectField(inetaddress,
+ gCachedFields.iaddr_ipaddress));
- char tmp[INET6_ADDRSTRLEN];
- int result = getnameinfo((sockaddr *)address, size, tmp, sizeof(tmp), NULL,
- 0, NI_NUMERICHOST);
- if (result != 0) {
- return result;
- }
-
- int port;
- if (withPort) {
- if (address->ss_family == AF_INET6) {
- sockaddr_in6 *sin6 = (sockaddr_in6 *) address;
- port = ntohs(sin6->sin6_port);
- snprintf(ipString, len, "[%s]:%d", tmp, port);
- } else {
- sockaddr_in *sin = (sockaddr_in *) address;
- port = ntohs(sin->sin_port);
- snprintf(ipString, len, "%s:%d", tmp, port);
- }
- } else {
- strncpy(ipString, tmp, len);
- }
- return 0;
+ return byteArrayToSocketAddress(env, addressBytes, port, sockaddress);
}
/**
@@ -491,30 +423,35 @@
* @param addressByteArray the byte array to convert.
*
* @return a string with the textual representation of the address.
- *
- * @throws SocketException the address family was unknown.
*/
-static jstring osNetworkSystem_byteArrayToIpString(JNIEnv *env, jclass clazz,
+static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jclass,
jbyteArray byteArray) {
- // For compatibility, ensure that an UnknownHostException is thrown if the
- // address is null.
if (byteArray == NULL) {
- jniThrowException(env, "java/net/UnknownHostException",
- strerror(EFAULT));
+ throwNullPointerException(env);
return NULL;
}
- struct sockaddr_storage ss;
- int ret = byteArrayToSocketAddress(env, byteArray, 0, &ss);
- if (ret) {
- jniThrowException(env, "java/net/UnknownHostException", strerror(ret));
+ sockaddr_storage ss;
+ if (!byteArrayToSocketAddress(env, byteArray, 0, &ss)) {
+ return NULL;
+ }
+ // TODO: getnameinfo seems to want its length parameter to be exactly
+ // sizeof(sockaddr_in) for an IPv4 address and sizeof (sockaddr_in6) for an
+ // IPv6 address. Fix getnameinfo so it accepts sizeof(sockaddr_storage), and
+ // then remove this hack.
+ int sa_size;
+ if (ss.ss_family == AF_INET) {
+ sa_size = sizeof(sockaddr_in);
+ } else if (ss.ss_family == AF_INET6) {
+ sa_size = sizeof(sockaddr_in6);
+ } else {
+ jniThrowBadAddressFamily(env);
return NULL;
}
char ipString[INET6_ADDRSTRLEN];
- ret = socketAddressToString(&ss, ipString, sizeof(ipString), false);
- if (ret) {
- env->ExceptionClear();
- jniThrowException(env, "java/net/UnknownHostException",
- gai_strerror(ret));
+ int rc = getnameinfo(reinterpret_cast<sockaddr*>(&ss), sa_size,
+ ipString, sizeof(ipString), NULL, 0, NI_NUMERICHOST);
+ if (rc != 0) {
+ jniThrowException(env, "java/net/UnknownHostException", gai_strerror(rc));
return NULL;
}
return env->NewStringUTF(ipString);
@@ -541,7 +478,7 @@
*
* @throws UnknownHostException the IP address was invalid.
*/
-static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv *env, jclass clazz,
+static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jclass,
jstring javaString) {
if (javaString == NULL) {
throwNullPointerException(env);
@@ -564,27 +501,34 @@
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
- sockaddr_in sin;
- addrinfo *res = NULL;
+ sockaddr_storage ss;
+ memset(&ss, 0, sizeof(ss));
+
+ addrinfo* res = NULL;
int ret = getaddrinfo(ipString, NULL, &hints, &res);
if (ret == 0 && res) {
- // Convert mapped addresses to IPv4 addresses if necessary.
- if (res->ai_family == AF_INET6 && isMappedAddress(res->ai_addr)) {
- convertMappedToIpv4((sockaddr_in6 *) res->ai_addr, &sin);
- result = socketAddressToByteArray(env, (sockaddr_storage *) &sin);
+ // Convert IPv4-mapped addresses to IPv4 addresses.
+ // The RI states "Java will never return an IPv4-mapped address".
+ sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(res->ai_addr);
+ if (res->ai_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+ sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&ss);
+ sin->sin_family = AF_INET;
+ sin->sin_port = sin6->sin6_port;
+ memcpy(&sin->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12], 4);
+ result = socketAddressToByteArray(env, &ss);
} else {
- result = socketAddressToByteArray(env,
- (sockaddr_storage *) res->ai_addr);
+ result = socketAddressToByteArray(env, reinterpret_cast<sockaddr_storage*>(res->ai_addr));
}
} else {
// For backwards compatibility, deal with address formats that
// getaddrinfo does not support. For example, 1.2.3, 1.3, and even 3 are
// valid IPv4 addresses according to the Java API. If getaddrinfo fails,
// try to use inet_aton.
- if (inet_aton(ipString, &sin.sin_addr)) {
- sin.sin_port = 0;
- sin.sin_family = AF_INET;
- result = socketAddressToByteArray(env, (sockaddr_storage *) &sin);
+ sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&ss);
+ if (inet_aton(ipString, &sin->sin_addr)) {
+ sin->sin_family = AF_INET;
+ sin->sin_port = 0;
+ result = socketAddressToByteArray(env, &ss);
}
}
@@ -609,8 +553,7 @@
*
* @return the new Boolean
*/
-
-jobject newJavaLangBoolean(JNIEnv * env, jint anInt) {
+static jobject newJavaLangBoolean(JNIEnv * env, jint anInt) {
jclass tempClass;
jmethodID tempMethod;
@@ -627,8 +570,7 @@
*
* @return the new Byte
*/
-
-jobject newJavaLangByte(JNIEnv * env, jbyte val) {
+static jobject newJavaLangByte(JNIEnv * env, jbyte val) {
jclass tempClass;
jmethodID tempMethod;
@@ -645,32 +587,21 @@
*
* @return the new Integer
*/
-
-jobject newJavaLangInteger(JNIEnv * env, jint anInt) {
- jclass tempClass;
- jmethodID tempMethod;
-
- tempClass = gCachedFields.integer_class;
- tempMethod = gCachedFields.integer_class_init;
- return env->NewObject(tempClass, tempMethod, anInt);
+static jobject newJavaLangInteger(JNIEnv* env, jint anInt) {
+ return env->NewObject(gCachedFields.integer_class, gCachedFields.integer_class_init, anInt);
}
-/**
- * Answer a new java.lang.String object.
- *
- * @param env pointer to the JNI library
- * @param anInt the byte[] constructor argument
- *
- * @return the new String
- */
+// Converts a number of milliseconds to a timeval.
+static timeval toTimeval(long ms) {
+ timeval tv;
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms - tv.tv_sec*1000) * 1000;
+ return tv;
+}
-jobject newJavaLangString(JNIEnv * env, jbyteArray bytes) {
- jclass tempClass;
- jmethodID tempMethod;
-
- tempClass = gCachedFields.string_class;
- tempMethod = gCachedFields.string_class_init;
- return env->NewObject(tempClass, tempMethod, (jbyteArray) bytes);
+// Converts a timeval to a number of milliseconds.
+static long toMs(const timeval& tv) {
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
/**
@@ -687,42 +618,10 @@
*/
static int time_msec_clock() {
- struct timeval tp;
+ timeval tp;
struct timezone tzp;
-
gettimeofday(&tp, &tzp);
- return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
-}
-
-/**
- * Check if the passed sockaddr_storage struct contains a localhost address
- *
- * @param address address pointer to the address to check
- *
- * @return 0 if the passed address isn't a localhost address
- */
-static int isLocalHost(struct sockaddr_storage *address) {
- if (address->ss_family == AF_INET) {
- struct sockaddr_in *sin = (struct sockaddr_in *) address;
- return (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK));
- } else if (address->ss_family == AF_INET6) {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) address;
- return IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr);
- } else {
- return 0;
- }
-}
-
-/**
- * Decide whether to use ADB networking for the given socket address.
- *
- * @param address pointer to sockaddr_storage structure to check
- *
- * @return true if ADB networking should be used, false otherwise.
- */
-static bool useAdbNetworkingForAddress(struct sockaddr_storage *address) {
- return useAdbNetworking && !isLocalHost(address) &&
- address->ss_family == AF_INET;
+ return toMs(tp);
}
/**
@@ -740,8 +639,6 @@
static const char * netLookupErrorString(int anErrorNum) {
switch (anErrorNum) {
- case SOCKERR_BADSOCKET:
- return "Bad socket";
case SOCKERR_NOTINITIALIZED:
return "Socket library uninitialized";
case SOCKERR_BADAF:
@@ -770,8 +667,6 @@
return "The address is already in use";
case SOCKERR_NOTBOUND:
return "The socket is not bound";
- case SOCKERR_UNKNOWNSOCKET:
- return "Resolution of the FileDescriptor to socket failed";
case SOCKERR_INVALIDTIMEOUT:
return "The specified timeout is invalid";
case SOCKERR_FDSETFULL:
@@ -907,12 +802,24 @@
}
}
-static int sockSelect(int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout) {
+static int selectWait(int fd, int uSecTime) {
+ timeval tv;
+ timeval* tvp;
+ if (uSecTime >= 0) {
+ /* Use a timeout if uSecTime >= 0 */
+ memset(&tv, 0, sizeof(tv));
+ tv.tv_usec = uSecTime;
+ tvp = &tv;
+ } else {
+ /* Infinite timeout if uSecTime < 0 */
+ tvp = NULL;
+ }
- int result = select(nfds, readfds, writefds, exceptfds, timeout);
-
- if (result < 0) {
+ fd_set readFds;
+ FD_ZERO(&readFds);
+ FD_SET(fd, &readFds);
+ int result = select(fd + 1, &readFds, NULL, NULL, tvp);
+ if (result == -1) {
if (errno == EINTR) {
result = SOCKERR_INTERRUPTED;
} else {
@@ -924,39 +831,10 @@
return result;
}
-#define SELECT_READ_TYPE 0
-#define SELECT_WRITE_TYPE 1
-
-static int selectWait(int handle, int uSecTime, int type) {
- fd_set fdset;
- struct timeval time, *timePtr;
- int result = 0;
- int size = handle + 1;
-
- FD_ZERO(&fdset);
- FD_SET(handle, &fdset);
-
- if (0 <= uSecTime) {
- /* Use a timeout if uSecTime >= 0 */
- memset(&time, 0, sizeof(time));
- time.tv_usec = uSecTime;
- timePtr = &time;
- } else {
- /* Infinite timeout if uSecTime < 0 */
- timePtr = NULL;
- }
-
- if (type == SELECT_READ_TYPE) {
- result = sockSelect(size, &fdset, NULL, NULL, timePtr);
- } else {
- result = sockSelect(size, NULL, &fdset, NULL, timePtr);
- }
- return result;
-}
-
-static int pollSelectWait(JNIEnv *env, jobject fileDescriptor, int timeout, int type) {
- /* now try reading the socket for the timespan timeout.
- * if timeout is 0 try forever until the soclets gets ready or until an
+// Returns 0 on success, not obviously meaningful negative values on error.
+static int pollSelectWait(JNIEnv *env, jobject fileDescriptor, int timeout) {
+ /* now try reading the socket for the timeout.
+ * if timeout is 0 try forever until the sockets gets ready or until an
* exception occurs.
*/
int pollTimeoutUSec = 100000, pollMsec = 100;
@@ -978,9 +856,8 @@
* Fetch the handle every time in case the socket is closed.
*/
handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_INTERRUPTED);
+ if (handle == -1) {
+ jniThrowSocketException(env, EINTR);
return -1;
}
@@ -990,7 +867,7 @@
pollTimeoutUSec = timeLeft <= 0 ? 0 : (timeLeft * 1000);
}
- result = selectWait(handle, pollTimeoutUSec, type);
+ result = selectWait(handle, pollTimeoutUSec);
/*
* because we are polling at a time smaller than timeout
@@ -1008,8 +885,7 @@
* effectively what has happened, even if we happen to
* have been interrupted.
*/
- jniThrowException(env, "java/net/SocketTimeoutException",
- netLookupErrorString(SOCKERR_TIMEOUT));
+ jniThrowSocketTimeoutException(env, ETIMEDOUT);
} else {
continue; // try again
}
@@ -1021,7 +897,7 @@
} else { /* polling with no timeout (why would you do this?)*/
- result = selectWait(handle, pollTimeoutUSec, type);
+ result = selectWait(handle, pollTimeoutUSec);
/*
* if interrupted (or a timeout) just retry
@@ -1041,121 +917,16 @@
}
/**
- * Obtain the socket address family from an existing socket.
- *
- * @param socket the filedescriptor of the socket to examine
- *
- * @return an integer, the address family of the socket
- */
-static int getSocketAddressFamily(int socket) {
- struct sockaddr_storage ss;
- socklen_t namelen = sizeof(ss);
- int ret = getsockname(socket, (struct sockaddr*) &ss, &namelen);
- if (ret != 0) {
- return AF_UNSPEC;
- } else {
- return ss.ss_family;
- }
-}
-
-/**
- * A helper method, to set the connect context to a Long object.
- *
- * @param env pointer to the JNI library
- * @param longclass Java Long Object
- */
-void setConnectContext(JNIEnv *env,jobject longclass,jbyte * context) {
- jclass descriptorCLS;
- jfieldID descriptorFID;
- descriptorCLS = env->FindClass("java/lang/Long");
- descriptorFID = env->GetFieldID(descriptorCLS, "value", "J");
- env->SetLongField(longclass, descriptorFID, (jlong)((jint)context));
-};
-
-/**
- * A helper method, to get the connect context.
- *
- * @param env pointer to the JNI library
- * @param longclass Java Long Object
- */
-jbyte *getConnectContext(JNIEnv *env, jobject longclass) {
- jclass descriptorCLS;
- jfieldID descriptorFID;
- descriptorCLS = env->FindClass("java/lang/Long");
- descriptorFID = env->GetFieldID(descriptorCLS, "value", "J");
- return (jbyte*) ((jint)env->GetLongField(longclass, descriptorFID));
-};
-
-// typical ip checksum
-unsigned short ip_checksum(unsigned short* buffer, int size) {
- register unsigned short * buf = buffer;
- register int bufleft = size;
- register unsigned long sum = 0;
-
- while (bufleft > 1) {
- sum = sum + (*buf++);
- bufleft = bufleft - sizeof(unsigned short );
- }
- if (bufleft) {
- sum = sum + (*(unsigned char*)buf);
- }
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
-
- return (unsigned short )(~sum);
-}
-
-
-/**
* Wrapper for connect() that converts IPv4 addresses to IPv4-mapped IPv6
* addresses if necessary.
*
- * @param socket the filedescriptor of the socket to connect
+ * @param socket the file descriptor of the socket to connect
* @param socketAddress the address to connect to
*/
-static int doConnect(int socket, struct sockaddr_storage *socketAddress) {
- sockaddr_storage mappedAddress;
- sockaddr_storage *realAddress;
- if (socketAddress->ss_family == AF_INET &&
- getSocketAddressFamily(socket) == AF_INET6) {
- convertIpv4ToMapped((sockaddr_in *) socketAddress,
- (sockaddr_in6 *) &mappedAddress, true);
- realAddress = &mappedAddress;
- } else {
- realAddress = socketAddress;
- }
- int ret;
- do {
- ret = connect(socket, (struct sockaddr *) realAddress,
- sizeof(struct sockaddr_storage));
- } while (ret < 0 && errno == EINTR);
- return ret;
-}
-
-/**
- * Wrapper for bind() that converts IPv4 addresses to IPv4-mapped IPv6
- * addresses if necessary.
- *
- * @param socket the filedescriptor of the socket to connect
- * @param socketAddress the address to connect to
- */
-static int doBind(int socket, struct sockaddr_storage *socketAddress) {
- struct sockaddr_storage mappedAddress;
- struct sockaddr_storage *realAddress;
- if (socketAddress->ss_family == AF_INET &&
- getSocketAddressFamily(socket) == AF_INET6) {
- convertIpv4ToMapped((sockaddr_in *) socketAddress,
- (sockaddr_in6 *) &mappedAddress, false);
- realAddress = &mappedAddress;
- } else {
- realAddress = socketAddress;
- }
- int ret;
- do {
- ret = bind(socket, (struct sockaddr *) realAddress,
- sizeof(struct sockaddr_storage));
- } while (ret < 0 && errno == EINTR);
- return ret;
+static int doConnect(int fd, const sockaddr_storage* socketAddress) {
+ sockaddr_storage tmp;
+ const sockaddr* realAddress = convertIpv4ToMapped(fd, socketAddress, &tmp, true);
+ return TEMP_FAILURE_RETRY(connect(fd, realAddress, sizeof(sockaddr_storage)));
}
/**
@@ -1179,43 +950,30 @@
*
* @return 0, if no errors occurred, otherwise the (negative) error code.
*/
-static int sockConnectWithTimeout(int handle, struct sockaddr_storage addr,
- unsigned int timeout, unsigned int step, jbyte *ctxt) {
+// TODO: do we really want to pass 'addr' by value?
+static int sockConnectWithTimeout(int handle, sockaddr_storage addr,
+ int timeout, unsigned int step, jbyte *ctxt) {
int rc = 0;
- struct timeval passedTimeout;
int errorVal;
socklen_t errorValLen = sizeof(int);
- struct selectFDSet *context = NULL;
+ selectFDSet* context = reinterpret_cast<selectFDSet*>(ctxt);
if (SOCKET_STEP_START == step) {
-
- context = (struct selectFDSet *) ctxt;
-
context->sock = handle;
context->nfds = handle + 1;
- if (useAdbNetworkingForAddress(&addr)) {
-
- // LOGD("+connect to address 0x%08x (via adb)",
- // addr.sin_addr.s_addr);
- rc = adb_networking_connect_fd(handle, (struct sockaddr_in *) &addr);
- // LOGD("-connect ret %d errno %d (via adb)", rc, errno);
-
- } else {
- /* set the socket to non-blocking */
- int block = JNI_TRUE;
- rc = ioctl(handle, FIONBIO, &block);
- if (0 != rc) {
- return convertError(rc);
- }
-
- // LOGD("+connect to address 0x%08x (via normal) on handle %d",
- // addr.sin_addr.s_addr, handle);
- rc = doConnect(handle, &addr);
- // LOGD("-connect to address 0x%08x (via normal) returned %d",
- // addr.sin_addr.s_addr, (int) rc);
-
+ /* set the socket to non-blocking */
+ int block = JNI_TRUE;
+ rc = ioctl(handle, FIONBIO, &block);
+ if (rc != 0) {
+ return convertError(rc);
}
+
+ // LOGD("+connect to address 0x%08x (via normal) on handle %d",
+ // addr.sin_addr.s_addr, handle);
+ rc = doConnect(handle, &addr);
+ // LOGD("-connect to address 0x%08x (via normal) returned %d",
+ // addr.sin_addr.s_addr, (int) rc);
if (rc == -1) {
rc = errno;
@@ -1236,19 +994,17 @@
} else if (SOCKET_STEP_CHECK == step) {
/* now check if we have connected yet */
- context = (struct selectFDSet *) ctxt;
-
/*
* set the timeout value to be used. Because on some unix platforms we
* don't get notified when a socket is closed we only sleep for 100ms
* at a time
+ *
+ * TODO: is this relevant for Android?
*/
- passedTimeout.tv_sec = 0;
if (timeout > 100) {
- passedTimeout.tv_usec = 100 * 1000;
- } else if ((int)timeout >= 0) {
- passedTimeout.tv_usec = timeout * 1000;
+ timeout = 100;
}
+ timeval passedTimeout(toTimeval(timeout));
/* initialize the FD sets for the select */
FD_ZERO(&(context->exceptionSet));
@@ -1262,7 +1018,7 @@
&(context->readSet),
&(context->writeSet),
&(context->exceptionSet),
- (int)timeout >= 0 ? &passedTimeout : NULL);
+ timeout >= 0 ? &passedTimeout : NULL);
/* if there is at least one descriptor ready to be checked */
if (0 < rc) {
@@ -1331,10 +1087,10 @@
switch(level) {
case SOL_SOCKET:
return "SOL_SOCKET";
- case SOL_IP:
- return "SOL_IP";
- case SOL_IPV6:
- return "SOL_IPV6";
+ case IPPROTO_IP:
+ return "IPPROTO_IP";
+ case IPPROTO_IPV6:
+ return "IPPROTO_IPV6";
default:
return "SOL_???";
}
@@ -1363,14 +1119,14 @@
switch (family) {
case AF_INET:
option = ipv4Option;
- protocol = SOL_IP;
+ protocol = IPPROTO_IP;
break;
case AF_INET6:
option = ipv6Option;
- protocol = SOL_IPV6;
+ protocol = IPPROTO_IPV6;
break;
default:
- // TODO: throw Java exceptions from this method instead of just
+ // TODO(enh): throw Java exceptions from this method instead of just
// returning error codes.
errno = EAFNOSUPPORT;
return -1;
@@ -1401,6 +1157,7 @@
return ret;
}
+#ifdef ENABLE_MULTICAST
/*
* Find the interface index that was set for this socket by the IP_MULTICAST_IF
* or IPV6_MULTICAST_IF socket option.
@@ -1413,20 +1170,19 @@
*/
static int interfaceIndexFromMulticastSocket(int socket) {
int family = getSocketAddressFamily(socket);
- socklen_t requestLength;
int interfaceIndex;
int result;
if (family == AF_INET) {
// IP_MULTICAST_IF returns a pointer to a struct ip_mreqn.
struct ip_mreqn tempRequest;
- requestLength = sizeof(tempRequest);
- result = getsockopt(socket, SOL_IP, IP_MULTICAST_IF, &tempRequest,
+ socklen_t requestLength = sizeof(tempRequest);
+ result = getsockopt(socket, IPPROTO_IP, IP_MULTICAST_IF, &tempRequest,
&requestLength);
interfaceIndex = tempRequest.imr_ifindex;
} else if (family == AF_INET6) {
// IPV6_MULTICAST_IF returns a pointer to an integer.
- requestLength = sizeof(interfaceIndex);
- result = getsockopt(socket, SOL_IPV6, IPV6_MULTICAST_IF,
+ socklen_t requestLength = sizeof(interfaceIndex);
+ result = getsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_IF,
&interfaceIndex, &requestLength);
} else {
errno = EAFNOSUPPORT;
@@ -1460,7 +1216,7 @@
*
* @exception SocketException if an error occurs during the call
*/
-static void mcastAddDropMembership (JNIEnv * env, int handle, jobject optVal,
+static void mcastAddDropMembership(JNIEnv *env, int handle, jobject optVal,
int ignoreIF, int setSockOptVal) {
struct sockaddr_storage sockaddrP;
int result;
@@ -1487,26 +1243,26 @@
interfaceIndex = interfaceIndexFromMulticastSocket(handle);
multicastRequest.imr_ifindex = interfaceIndex;
if (interfaceIndex == -1) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
}
// Convert the inetAddress to an IPv4 address structure.
- result = inetAddressToSocketAddress(env, optVal, 0, &sockaddrP);
- if (result < 0) // Exception has already been thrown.
+ if (!inetAddressToSocketAddress(env, optVal, 0, &sockaddrP)) {
return;
+ }
if (sockaddrP.ss_family != AF_INET) {
- throwSocketException(env, SOCKERR_BADAF);
+ jniThrowSocketException(env, EAFNOSUPPORT);
return;
}
struct sockaddr_in *sin = (struct sockaddr_in *) &sockaddrP;
multicastRequest.imr_multiaddr = sin->sin_addr;
- result = setsockopt(handle, SOL_IP, setSockOptVal,
+ result = setsockopt(handle, IPPROTO_IP, setSockOptVal,
&multicastRequest, length);
if (0 != result) {
- throwSocketException (env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
} else {
@@ -1531,9 +1287,9 @@
interfaceIndex = env->GetIntField(optVal, interfaceIdxID);
}
- result = inetAddressToSocketAddress(env, multiaddr, 0, &sockaddrP);
- if (result < 0) // Exception has already been thrown.
+ if (!inetAddressToSocketAddress(env, multiaddr, 0, &sockaddrP)) {
return;
+ }
int family = getSocketAddressFamily(handle);
@@ -1555,7 +1311,7 @@
((struct sockaddr_in *) &sockaddrP)->sin_addr;
ipv4Request.imr_ifindex = interfaceIndex;
multicastRequest = &ipv4Request;
- level = SOL_IP;
+ level = IPPROTO_IP;
break;
case AF_INET6:
// setSockOptVal is passed in by the caller and may be IPv4-only
@@ -1571,38 +1327,28 @@
((struct sockaddr_in6 *) &sockaddrP)->sin6_addr;
ipv6Request.ipv6mr_interface = interfaceIndex;
multicastRequest = &ipv6Request;
- level = SOL_IPV6;
+ level = IPPROTO_IPV6;
break;
default:
- throwSocketException (env, SOCKERR_BADAF);
- return;
+ jniThrowSocketException(env, EAFNOSUPPORT);
+ return;
}
/* join/drop the multicast address */
result = setsockopt(handle, level, setSockOptVal, multicastRequest,
requestLength);
if (0 != result) {
- throwSocketException (env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
}
}
+#endif // def ENABLE_MULTICAST
static void osNetworkSystem_oneTimeInitializationImpl(JNIEnv* env, jobject obj,
jboolean jcl_supports_ipv6) {
// LOGD("ENTER oneTimeInitializationImpl of OSNetworkSystem");
- char useAdbNetworkingProperty[PROPERTY_VALUE_MAX];
- char adbConnectedProperty[PROPERTY_VALUE_MAX];
-
- property_get("android.net.use-adb-networking", useAdbNetworkingProperty, "");
- property_get("adb.connected", adbConnectedProperty, "");
-
- if (strlen((char *)useAdbNetworkingProperty) > 0
- && strlen((char *)adbConnectedProperty) > 0) {
- useAdbNetworking = 1;
- }
-
memset(&gCachedFields, 0, sizeof(gCachedFields));
struct CachedFields *c = &gCachedFields;
@@ -1616,7 +1362,6 @@
{&c->integer_class, "java/lang/Integer"},
{&c->boolean_class, "java/lang/Boolean"},
{&c->byte_class, "java/lang/Byte"},
- {&c->string_class, "java/lang/String"},
{&c->socketimpl_class, "java/net/SocketImpl"},
{&c->dpack_class, "java/net/DatagramPacket"}
};
@@ -1638,7 +1383,6 @@
{&c->integer_class_init, c->integer_class, "<init>", "(I)V", false},
{&c->boolean_class_init, c->boolean_class, "<init>", "(Z)V", false},
{&c->byte_class_init, c->byte_class, "<init>", "(B)V", false},
- {&c->string_class_init, c->string_class, "<init>", "([B)V", false},
{&c->iaddr_getbyaddress, c->iaddr_class, "getByAddress",
"([B)Ljava/net/InetAddress;", true}
};
@@ -1703,8 +1447,7 @@
sock = socket(PF_INET, type, 0);
}
if (sock < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ jniThrowSocketException(env, errno);
return sock;
}
jniSetFileDescriptorOfFD(env, fileDescriptor, sock);
@@ -1724,77 +1467,53 @@
}
static jint osNetworkSystem_readSocketDirectImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jint address, jint offset, jint count,
- jint timeout) {
+ jobject fileDescriptor, jint address, jint count, jint timeout) {
// LOGD("ENTER readSocketDirectImpl");
- int handle;
- jbyte *message = (jbyte *)address + offset;
- int result, ret, localCount;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
return 0;
}
- result = selectWait(handle, timeout, SELECT_READ_TYPE);
-
- if (0 > result) {
- return 0;
+ if (timeout != 0) {
+ int result = selectWait(fd, timeout * 1000);
+ if (result < 0) {
+ return 0;
+ }
}
- localCount = (count < 65536) ? count : 65536;
-
- do {
- ret = recv(handle, (jbyte *) message, localCount, SOCKET_NOFLAGS);
- } while (ret < 0 && errno == EINTR);
-
- if (0 == ret) {
+ jbyte* dst = reinterpret_cast<jbyte*>(static_cast<uintptr_t>(address));
+ ssize_t bytesReceived =
+ TEMP_FAILURE_RETRY(recv(fd, dst, count, SOCKET_NOFLAGS));
+ if (bytesReceived == 0) {
return -1;
- } else if (ret == -1) {
- int err = convertError(errno);
- throwSocketException(env, err);
- return 0;
+ } else if (bytesReceived == -1) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ // We were asked to read a non-blocking socket with no data
+ // available, so report "no bytes read".
+ return 0;
+ } else {
+ jniThrowSocketException(env, errno);
+ return 0;
+ }
}
- return ret;
+ return bytesReceived;
}
static jint osNetworkSystem_readSocketImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jbyteArray data, jint offset, jint count,
+ jobject fileDescriptor, jbyteArray byteArray, jint offset, jint count,
jint timeout) {
// LOGD("ENTER readSocketImpl");
- jbyte *message;
- int result, localCount;
-
- jbyte internalBuffer[BUFFERSIZE];
-
- localCount = (count < 65536) ? count : 65536;
-
- if (localCount > BUFFERSIZE) {
- message = (jbyte*)malloc(localCount * sizeof(jbyte));
- if (message == NULL) {
- jniThrowException(env, "java/lang/OutOfMemoryError",
- "couldn't allocate enough memory for readSocket");
- return 0;
- }
- } else {
- message = (jbyte *)internalBuffer;
+ jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
+ if (bytes == NULL) {
+ return -1;
}
-
- result = osNetworkSystem_readSocketDirectImpl(env, clazz, fileDescriptor,
- (jint) message, 0, localCount, timeout);
-
- if (result > 0) {
- env->SetByteArrayRegion(data, offset, result, (jbyte *)message);
- }
-
- if (((jbyte *)message) != internalBuffer) {
- free(( jbyte *)message);
- }
-
+ jint address =
+ static_cast<jint>(reinterpret_cast<uintptr_t>(bytes + offset));
+ int result = osNetworkSystem_readSocketDirectImpl(env, clazz,
+ fileDescriptor, address, count, timeout);
+ env->ReleaseByteArrayElements(byteArray, bytes, 0);
return result;
}
@@ -1802,95 +1521,42 @@
jobject fileDescriptor, jint address, jint offset, jint count) {
// LOGD("ENTER writeSocketDirectImpl");
- int handle;
- jbyte *message = (jbyte *)address + offset;
- int result = 0, sent = 0;
-
if (count <= 0) {
return 0;
}
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
return 0;
}
- result = send(handle, (jbyte *) message, (int) count, SOCKET_NOFLAGS);
- if (result < 0) {
- int err = convertError(errno);
-
- if (SOCKERR_WOULDBLOCK == err){
- jclass socketExClass,errorCodeExClass;
- jmethodID errorCodeExConstructor, socketExConstructor,socketExCauseMethod;
- jobject errorCodeEx, socketEx;
- const char* errorMessage = netLookupErrorString(err);
- jstring errorMessageString = env->NewStringUTF(errorMessage);
-
- errorCodeExClass = env->FindClass("org/apache/harmony/luni/util/ErrorCodeException");
- if (!errorCodeExClass){
- return 0;
- }
- errorCodeExConstructor = env->GetMethodID(errorCodeExClass,"<init>","(I)V");
- if (!errorCodeExConstructor){
- return 0;
- }
- errorCodeEx = env->NewObject(errorCodeExClass,errorCodeExConstructor,err);
-
- socketExClass = env->FindClass("java/net/SocketException");
- if (!socketExClass) {
- return 0;
- }
- socketExConstructor = env->GetMethodID(socketExClass,"<init>","(Ljava/lang/String;)V");
- if (!socketExConstructor) {
- return 0;
- }
- socketEx = env->NewObject(socketExClass, socketExConstructor, errorMessageString);
- socketExCauseMethod = env->GetMethodID(socketExClass,"initCause","(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
- env->CallObjectMethod(socketEx,socketExCauseMethod,errorCodeEx);
- env->Throw((jthrowable)socketEx);
+ jbyte* message = reinterpret_cast<jbyte*>(static_cast<uintptr_t>(address + offset));
+ int bytesSent = send(fd, message, count, SOCKET_NOFLAGS);
+ if (bytesSent == -1) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ // We were asked to write to a non-blocking socket, but were told
+ // it would block, so report "no bytes written".
+ return 0;
+ } else {
+ jniThrowSocketException(env, errno);
return 0;
}
- throwSocketException(env, err);
- return 0;
}
-
- return result;
+ return bytesSent;
}
static jint osNetworkSystem_writeSocketImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jbyteArray data, jint offset, jint count) {
+ jobject fileDescriptor, jbyteArray byteArray, jint offset, jint count) {
// LOGD("ENTER writeSocketImpl");
- jbyte *message;
- int sent = 0;
- jint result = 0;
-
-/* TODO: ARRAY PINNING */
-#define INTERNAL_SEND_BUFFER_MAX 512
- jbyte internalBuffer[INTERNAL_SEND_BUFFER_MAX];
-
- if (count > INTERNAL_SEND_BUFFER_MAX) {
- message = (jbyte*)malloc(count * sizeof( jbyte));
- if (message == NULL) {
- jniThrowException(env, "java/lang/OutOfMemoryError",
- "couldn't allocate enough memory for writeSocket");
- return 0;
- }
- } else {
- message = (jbyte *)internalBuffer;
+ jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
+ if (bytes == NULL) {
+ return -1;
}
-
- env->GetByteArrayRegion(data, offset, count, message);
-
- result = osNetworkSystem_writeSocketDirectImpl(env, clazz, fileDescriptor,
- (jint) message, 0, count);
-
- if (( jbyte *)message != internalBuffer) {
- free(( jbyte *)message);
- }
-#undef INTERNAL_SEND_BUFFER_MAX
+ jint address = static_cast<jint>(reinterpret_cast<uintptr_t>(bytes));
+ int result = osNetworkSystem_writeSocketDirectImpl(env, clazz,
+ fileDescriptor, address, offset, count);
+ env->ReleaseByteArrayElements(byteArray, bytes, 0);
return result;
}
@@ -1899,69 +1565,49 @@
// LOGD("ENTER setNonBlockingImpl");
int handle;
- int result;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ if (!jniGetFd(env, fileDescriptor, handle)) {
return;
}
int block = nonblocking;
-
- result = ioctl(handle, FIONBIO, &block);
-
- if (result == -1) {
- throwSocketException(env, convertError(errno));
+ int rc = ioctl(handle, FIONBIO, &block);
+ if (rc == -1) {
+ jniThrowSocketException(env, errno);
}
}
-static jint osNetworkSystem_connectSocketImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jint trafficClass, jobject inetAddr, jint port);
-
static jint osNetworkSystem_connectWithTimeoutSocketImpl(JNIEnv* env,
jclass clazz, jobject fileDescriptor, jint timeout, jint trafficClass,
jobject inetAddr, jint port, jint step, jbyteArray passContext) {
// LOGD("ENTER connectWithTimeoutSocketImpl");
- int handle;
- int result = 0;
- struct sockaddr_storage address;
- jbyte *context = NULL;
-
- result = inetAddressToSocketAddress(env, inetAddr, port, &address);
- if (result < 0)
- return result;
-
- // Check if we're using adb networking and redirect in case it is used.
- if (useAdbNetworkingForAddress(&address)) {
- return osNetworkSystem_connectSocketImpl(env, clazz, fileDescriptor,
- trafficClass, inetAddr, port);
- }
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ sockaddr_storage address;
+ if (!inetAddressToSocketAddress(env, inetAddr, port, &address)) {
return -1;
}
- context = (jbyte *)env->GetPrimitiveArrayCritical(passContext, NULL);
-
- switch (step) {
- case SOCKET_CONNECT_STEP_START:
- result = sockConnectWithTimeout(handle, address, 0,
- SOCKET_STEP_START, context);
- break;
- case SOCKET_CONNECT_STEP_CHECK:
- result = sockConnectWithTimeout(handle, address, timeout,
- SOCKET_STEP_CHECK, context);
- break;
+ int handle;
+ if (!jniGetFd(env, fileDescriptor, handle)) {
+ return -1;
}
- env->ReleasePrimitiveArrayCritical(passContext, context, JNI_ABORT);
+ jbyte* context = env->GetByteArrayElements(passContext, NULL);
+ int result = 0;
+ switch (step) {
+ case SOCKET_CONNECT_STEP_START:
+ result = sockConnectWithTimeout(handle, address, 0,
+ SOCKET_STEP_START, context);
+ break;
+ case SOCKET_CONNECT_STEP_CHECK:
+ result = sockConnectWithTimeout(handle, address, timeout,
+ SOCKET_STEP_CHECK, context);
+ break;
+ default:
+ assert(false);
+ }
+ env->ReleaseByteArrayElements(passContext, context, 0);
- if (0 == result) {
+ if (result == 0) {
/* connected , so stop here */
sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, NULL);
} else if (result != SOCKERR_NOTCONNECTED) {
@@ -1985,7 +1631,6 @@
// LOGD("ENTER connectStreamWithTimeoutSocketImpl");
int result = 0;
- int handle;
struct sockaddr_storage address;
jbyte *context = NULL;
int remainingTimeout = timeout;
@@ -1999,23 +1644,12 @@
finishTime = time_msec_clock() + (int) timeout;
}
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ int handle;
+ if (!jniGetFd(env, fileDescriptor, handle)) {
return;
}
- result = inetAddressToSocketAddress(env, inetAddr, remotePort, &address);
- if (result < 0) // Exception has already been thrown.
- return;
-
- // Check if we're using adb networking and redirect in case it is used.
- if (useAdbNetworkingForAddress(&address)) {
- int retVal = osNetworkSystem_connectSocketImpl(env, clazz,
- fileDescriptor, trafficClass, inetAddr, remotePort);
- if (retVal != 0) {
- throwSocketException(env, SOCKERR_BADSOCKET);
- }
+ if (!inetAddressToSocketAddress(env, inetAddr, remotePort, &address)) {
return;
}
@@ -2024,8 +1658,8 @@
* the descriptor sets that we will use
*/
context =(jbyte *) malloc(sizeof(struct selectFDSet));
- if (NULL == context) {
- throwSocketException(env, SOCKERR_NOBUFFERS);
+ if (context == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", "native heap");
return;
}
@@ -2063,10 +1697,10 @@
* are connected if the socket is closed on them.
*/
handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
+ if (handle == -1) {
sockConnectWithTimeout(handle, address, 0,
SOCKET_STEP_DONE, context);
- throwSocketException(env, SOCKERR_BADSOCKET);
+ jniThrowSocketException(env, EBADF);
goto bail;
}
@@ -2091,9 +1725,7 @@
if (remainingTimeout <= 0) {
sockConnectWithTimeout(handle, address, 0,
SOCKET_STEP_DONE, context);
- jniThrowException(env,
- "java/net/SocketTimeoutException",
- netLookupErrorString(result));
+ jniThrowSocketTimeoutException(env, ENOTCONN);
goto bail;
}
} else {
@@ -2127,98 +1759,40 @@
}
}
-static jint osNetworkSystem_connectSocketImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jint trafficClass, jobject inetAddr, jint port) {
- //LOGD("ENTER direct-call connectSocketImpl\n");
-
- struct sockaddr_storage address;
- int ret;
- int handle;
-
- ret = inetAddressToSocketAddress(env, inetAddr, port, &address);
- if (ret < 0)
- return ret;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
- return -1;
- }
-
- if (useAdbNetworkingForAddress(&address)) {
-
- // LOGD("+connect to address 0x%08x port %d (via adb)",
- // address.sin_addr.s_addr, (int) port);
- ret = adb_networking_connect_fd(handle, (struct sockaddr_in *) &address);
- // LOGD("-connect ret %d errno %d (via adb)", ret, errno);
-
- } else {
-
- // call this method with a timeout of zero
- osNetworkSystem_connectStreamWithTimeoutSocketImpl(env, clazz,
- fileDescriptor, port, 0, trafficClass, inetAddr);
- if (env->ExceptionOccurred() != 0) {
- return -1;
- } else {
- return 0;
- }
-
- }
-
- if (ret < 0) {
- jniThrowException(env, "java/net/ConnectException",
- netLookupErrorString(convertError(errno)));
- return ret;
- }
-
- return ret;
-}
-
static void osNetworkSystem_socketBindImpl(JNIEnv* env, jclass clazz,
jobject fileDescriptor, jint port, jobject inetAddress) {
// LOGD("ENTER socketBindImpl");
- struct sockaddr_storage sockaddress;
- int ret;
- int handle;
-
- ret = inetAddressToSocketAddress(env, inetAddress, port, &sockaddress);
- if (ret < 0)
- return;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ sockaddr_storage socketAddress;
+ if (!inetAddressToSocketAddress(env, inetAddress, port, &socketAddress)) {
return;
}
- ret = doBind(handle, &sockaddress);
- if (ret < 0) {
- jniThrowException(env, "java/net/BindException",
- netLookupErrorString(convertError(errno)));
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
return;
}
+
+ sockaddr_storage tmp;
+ const sockaddr* realAddress = convertIpv4ToMapped(fd, &socketAddress, &tmp, false);
+ int rc = TEMP_FAILURE_RETRY(bind(fd, realAddress, sizeof(sockaddr_storage)));
+ if (rc == -1) {
+ jniThrowBindException(env, errno);
+ }
}
static void osNetworkSystem_listenStreamSocketImpl(JNIEnv* env, jclass clazz,
jobject fileDescriptor, jint backlog) {
// LOGD("ENTER listenStreamSocketImpl");
- int ret;
int handle;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ if (!jniGetFd(env, fileDescriptor, handle)) {
return;
}
- ret = listen(handle, backlog);
-
- if (ret < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ int rc = listen(handle, backlog);
+ if (rc == -1) {
+ jniThrowSocketException(env, errno);
return;
}
}
@@ -2228,18 +1802,13 @@
// LOGD("ENTER availableStreamImpl");
int handle;
- char message[BUFFERSIZE];
-
- int result;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ if (!jniGetFd(env, fileDescriptor, handle)) {
return 0;
}
+ int result;
do {
- result = selectWait(handle, 1, SELECT_READ_TYPE);
+ result = selectWait(handle, 1);
if (SOCKERR_TIMEOUT == result) {
// The read operation timed out, so answer 0 bytes available
@@ -2252,67 +1821,54 @@
}
} while (SOCKERR_INTERRUPTED == result);
- result = recv(handle, (jbyte *) message, BUFFERSIZE, MSG_PEEK);
+ char message[2048];
+ result = recv(handle, (jbyte *) message, sizeof(message), MSG_PEEK);
if (0 > result) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ jniThrowSocketException(env, errno);
return 0;
}
return result;
}
-static void osNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass clazz,
- jobject fdServer, jobject newSocket, jobject fdnewSocket, jint timeout) {
+static void osNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass,
+ jobject serverFileDescriptor,
+ jobject newSocket, jobject clientFileDescriptor, jint timeout) {
// LOGD("ENTER acceptSocketImpl");
- struct sockaddr_storage sa;
-
- int ret;
- int retFD;
- int result;
- int handle;
- socklen_t addrlen;
-
if (newSocket == NULL) {
throwNullPointerException(env);
return;
}
- result = pollSelectWait(env, fdServer, timeout, SELECT_READ_TYPE);
- if (0 > result) {
+ int rc = pollSelectWait(env, serverFileDescriptor, timeout);
+ if (rc < 0) {
return;
}
- handle = jniGetFDFromFileDescriptor(env, fdServer);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ int serverFd;
+ if (!jniGetFd(env, serverFileDescriptor, serverFd)) {
return;
}
- do {
- addrlen = sizeof(sa);
- ret = accept(handle, (struct sockaddr *) &sa, &addrlen);
- } while (ret < 0 && errno == EINTR);
-
- if (ret < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ sockaddr_storage sa;
+ socklen_t addrlen = sizeof(sa);
+ int clientFd = TEMP_FAILURE_RETRY(accept(serverFd,
+ reinterpret_cast<sockaddr*>(&sa), &addrlen));
+ if (clientFd == -1) {
+ jniThrowSocketException(env, errno);
return;
}
- retFD = ret;
-
/*
* For network sockets, put the peer address and port in instance variables.
* We don't bother to do this for UNIX domain sockets, since most peers are
* anonymous anyway.
*/
if (sa.ss_family == AF_INET || sa.ss_family == AF_INET6) {
- jobject inetAddress = socketAddressToInetAddress(env, &sa);
- if (ret == -1) {
- close(retFD);
- newSocket = NULL; // Exception has already been thrown.
+ jobject inetAddress = socketAddressToInetAddress(env, &sa);
+ if (inetAddress == NULL) {
+ close(clientFd);
return;
}
@@ -2323,21 +1879,16 @@
env->SetIntField(newSocket, gCachedFields.socketimpl_port, port);
}
- jniSetFileDescriptorOfFD(env, fdnewSocket, retFD);
+ jniSetFileDescriptorOfFD(env, clientFileDescriptor, clientFd);
}
static jboolean osNetworkSystem_supportsUrgentDataImpl(JNIEnv* env,
jclass clazz, jobject fileDescriptor) {
// LOGD("ENTER supportsUrgentDataImpl");
- int handle;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- return JNI_FALSE;
- }
-
- return JNI_TRUE;
+ // TODO(enh): do we really need to exclude the invalid file descriptor case?
+ int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ return (fd == -1) ? JNI_FALSE : JNI_TRUE;
}
static void osNetworkSystem_sendUrgentDataImpl(JNIEnv* env, jclass clazz,
@@ -2345,132 +1896,128 @@
// LOGD("ENTER sendUrgentDataImpl");
int handle;
- int result;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ if (!jniGetFd(env, fileDescriptor, handle)) {
return;
}
- result = send(handle, (jbyte *) &value, 1, MSG_OOB);
- if (result < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ int rc = send(handle, &value, 1, MSG_OOB);
+ if (rc == -1) {
+ jniThrowSocketException(env, errno);
}
}
-static void osNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass clazz,
- jobject fd, jint port, jint trafficClass, jobject inetAddress) {
+static void osNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass,
+ jobject fileDescriptor, jint port, jint trafficClass, jobject inetAddress) {
// LOGD("ENTER connectDatagramImpl2");
- int handle = jniGetFDFromFileDescriptor(env, fd);
-
- struct sockaddr_storage sockAddr;
- int ret;
-
- ret = inetAddressToSocketAddress(env, inetAddress, port, &sockAddr);
- if (ret < 0) // Exception has already been thrown.
+ sockaddr_storage sockAddr;
+ if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) {
return;
+ }
- ret = doConnect(handle, &sockAddr);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return;
+ }
+
+ int ret = doConnect(fd, &sockAddr);
if (ret < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ jniThrowSocketException(env, errno);
}
}
-static void osNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass clazz,
- jobject fd) {
+static void osNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass,
+ jobject fileDescriptor) {
// LOGD("ENTER disconnectDatagramImpl");
- int handle = jniGetFDFromFileDescriptor(env, fd);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return;
+ }
- struct sockaddr_storage sockAddr;
+ sockaddr_storage sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.ss_family = AF_UNSPEC;
- int result = doConnect(handle, &sockAddr);
+ int result = doConnect(fd, &sockAddr);
if (result < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ jniThrowSocketException(env, errno);
}
}
+static void osNetworkSystem_setInetAddressImpl(JNIEnv* env, jobject,
+ jobject sender, jbyteArray address) {
+ // LOGD("ENTER setInetAddressImpl");
+
+ env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address);
+}
+
static jint osNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz,
- jobject fd, jobject sender, jint receiveTimeout) {
+ jobject fileDescriptor, jobject sender, jint receiveTimeout) {
// LOGD("ENTER peekDatagramImpl");
- int port = -1;
-
- int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE);
- if (0> result) {
- return (jint) 0;
- }
-
- int handle = jniGetFDFromFileDescriptor(env, fd);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
+ if (result < 0) {
return 0;
}
- struct sockaddr_storage sockAddr;
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return 0;
+ }
+
+ sockaddr_storage sockAddr;
socklen_t sockAddrLen = sizeof(sockAddr);
- ssize_t length;
- do {
- length = recvfrom(handle, NULL, 0, MSG_PEEK,
- (struct sockaddr *)&sockAddr, &sockAddrLen);
- } while (length < 0 && errno == EINTR);
- if (length < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ ssize_t length = TEMP_FAILURE_RETRY(recvfrom(fd, NULL, 0, MSG_PEEK,
+ reinterpret_cast<sockaddr*>(&sockAddr), &sockAddrLen));
+ if (length == -1) {
+ jniThrowSocketException(env, errno);
return 0;
}
- sender = socketAddressToInetAddress(env, &sockAddr);
- if (sender == NULL) // Exception has already been thrown.
+ // We update the byte[] in the 'sender' InetAddress, and return the port.
+ // This awful API is public in the RI, so there's no point returning
+ // InetSocketAddress here instead.
+ jbyteArray senderAddressArray = socketAddressToByteArray(env, &sockAddr);
+ if (sender == NULL) {
return -1;
-
- port = getSocketAddressPort(&sockAddr);
- return port;
+ }
+ osNetworkSystem_setInetAddressImpl(env, NULL, sender, senderAddressArray);
+ return getSocketAddressPort(&sockAddr);
}
static jint osNetworkSystem_receiveDatagramDirectImpl(JNIEnv* env, jclass clazz,
- jobject fd, jobject packet, jint address, jint offset, jint length,
- jint receiveTimeout, jboolean peek) {
+ jobject fileDescriptor, jobject packet, jint address, jint offset,
+ jint length, jint receiveTimeout, jboolean peek) {
// LOGD("ENTER receiveDatagramDirectImpl");
- int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE);
- if (0 > result) {
- return (jint) 0;
- }
-
- int handle = jniGetFDFromFileDescriptor(env, fd);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
+ if (result < 0) {
return 0;
}
- struct sockaddr_storage sockAddr;
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return 0;
+ }
+
+ char* buf =
+ reinterpret_cast<char*>(static_cast<uintptr_t>(address + offset));
+ const int mode = peek ? MSG_PEEK : 0;
+ sockaddr_storage sockAddr;
socklen_t sockAddrLen = sizeof(sockAddr);
-
- int mode = peek ? MSG_PEEK : 0;
-
- ssize_t actualLength;
- do {
- actualLength = recvfrom(handle, (char*)(address + offset), length, mode,
- (struct sockaddr *)&sockAddr, &sockAddrLen);
- } while (actualLength < 0 && errno == EINTR);
- if (actualLength < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
+ ssize_t actualLength = TEMP_FAILURE_RETRY(recvfrom(fd, buf, length, mode,
+ reinterpret_cast<sockaddr*>(&sockAddr), &sockAddrLen));
+ if (actualLength == -1) {
+ jniThrowSocketException(env, errno);
return 0;
}
if (packet != NULL) {
jbyteArray addr = socketAddressToByteArray(env, &sockAddr);
- if (addr == NULL) // Exception has already been thrown.
+ if (addr == NULL) {
return 0;
+ }
int port = getSocketAddressPort(&sockAddr);
jobject sender = env->CallStaticObjectMethod(
gCachedFields.iaddr_class, gCachedFields.iaddr_getbyaddress,
@@ -2508,34 +2055,30 @@
}
static jint osNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv* env,
- jclass clazz, jobject fd, jobject packet, jint address, jint offset,
- jint length, jint receiveTimeout, jboolean peek) {
+ jclass clazz, jobject fileDescriptor, jobject packet,
+ jint address, jint offset, jint length,
+ jint receiveTimeout, jboolean peek) {
// LOGD("ENTER receiveConnectedDatagramDirectImpl");
- int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE);
-
- if (0 > result) {
+ int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
+ if (result < 0) {
return 0;
}
- int handle = jniGetFDFromFileDescriptor(env, fd);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
return 0;
}
-
+
+ char* buf = reinterpret_cast<char*>(static_cast<uintptr_t>(address + offset));
int mode = peek ? MSG_PEEK : 0;
-
- int actualLength = recvfrom(handle,
- (char*)(address + offset), length, mode, NULL, NULL);
-
+ int actualLength = recvfrom(fd, buf, length, mode, NULL, NULL);
if (actualLength < 0) {
jniThrowException(env, "java/net/PortUnreachableException", "");
return 0;
}
- if ( packet != NULL) {
+ if (packet != NULL) {
env->SetIntField(packet, gCachedFields.dpack_length, actualLength);
}
return actualLength;
@@ -2567,39 +2110,34 @@
}
static jint osNetworkSystem_sendDatagramDirectImpl(JNIEnv* env, jclass clazz,
- jobject fd, jint address, jint offset, jint length, jint port,
+ jobject fileDescriptor, jint address, jint offset, jint length,
+ jint port,
jboolean bindToDevice, jint trafficClass, jobject inetAddress) {
// LOGD("ENTER sendDatagramDirectImpl");
- int handle = jniGetFDFromFileDescriptor(env, fd);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
- return 0;
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return -1;
}
- struct sockaddr_storage receiver;
- if (inetAddressToSocketAddress(env, inetAddress, port, &receiver) < 0) {
- // Exception has already been thrown.
- return 0;
+ sockaddr_storage receiver;
+ if (!inetAddressToSocketAddress(env, inetAddress, port, &receiver)) {
+ return -1;
}
- ssize_t result = 0;
- do {
- result = sendto(handle, (char*)(address + offset), length,
- SOCKET_NOFLAGS, (struct sockaddr*)&receiver, sizeof(receiver));
- } while (result < 0 && errno == EINTR);
- if (result < 0) {
- int err = convertError(errno);
- if ((SOCKERR_CONNRESET == err)
- || (SOCKERR_CONNECTION_REFUSED == err)) {
+ char* buf =
+ reinterpret_cast<char*>(static_cast<uintptr_t>(address + offset));
+ ssize_t bytesSent = TEMP_FAILURE_RETRY(sendto(fd, buf, length,
+ SOCKET_NOFLAGS,
+ reinterpret_cast<sockaddr*>(&receiver), sizeof(receiver)));
+ if (bytesSent == -1) {
+ if (errno == ECONNRESET || errno == ECONNREFUSED) {
return 0;
} else {
- throwSocketException(env, err);
- return 0;
+ jniThrowSocketException(env, errno);
}
}
- return (jint) result;
+ return bytesSent;
}
static jint osNetworkSystem_sendDatagramImpl(JNIEnv* env, jclass clazz,
@@ -2617,29 +2155,27 @@
}
static jint osNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv* env,
- jclass clazz, jobject fd, jint address, jint offset, jint length,
+ jclass clazz, jobject fileDescriptor,
+ jint address, jint offset, jint length,
jboolean bindToDevice) {
// LOGD("ENTER sendConnectedDatagramDirectImpl");
- int handle = jniGetFDFromFileDescriptor(env, fd);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
return 0;
}
- int result = send(handle, (char*)(address + offset), length, 0);
-
- if (result < 0) {
- int err = convertError(errno);
- if ((SOCKERR_CONNRESET == err) || (SOCKERR_CONNECTION_REFUSED == err)) {
+ char* buf =
+ reinterpret_cast<char*>(static_cast<uintptr_t>(address + offset));
+ ssize_t bytesSent = TEMP_FAILURE_RETRY(send(fd, buf, length, 0));
+ if (bytesSent == -1) {
+ if (errno == ECONNRESET || errno == ECONNREFUSED) {
return 0;
} else {
- throwSocketException(env, err);
- return 0;
+ jniThrowSocketException(env, errno);
}
}
- return result;
+ return bytesSent;
}
static jint osNetworkSystem_sendConnectedDatagramImpl(JNIEnv* env, jclass clazz,
@@ -2660,186 +2196,53 @@
// LOGD("ENTER createServerStreamSocketImpl");
int handle = createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
- if (handle < 0)
+ if (handle < 0) {
return;
+ }
int value = 1;
setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
}
-/*
- * @param timeout in milliseconds. If zero, block until data received
- */
-static jint osNetworkSystem_receiveStreamImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jbyteArray data, jint offset, jint count,
- jint timeout) {
- // LOGD("ENTER receiveStreamImpl");
-
- int result;
- int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
- return 0;
+static void doShutdown(JNIEnv* env, jobject fileDescriptor, int how) {
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return;
}
-
- // Cap read length to available buf size
- int spaceAvailable = env->GetArrayLength(data) - offset;
- int localCount = count < spaceAvailable? count : spaceAvailable;
-
- jboolean isCopy;
- jbyte *body = env->GetByteArrayElements(data, &isCopy);
-
- // set timeout
- struct timeval tv;
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv,
- sizeof(struct timeval));
-
- do {
- result = recv(handle, body + offset, localCount, SOCKET_NOFLAGS);
- } while (result < 0 && errno == EINTR);
-
- env->ReleaseByteArrayElements(data, body, 0);
-
- /*
- * If no bytes are read, return -1 to signal 'endOfFile'
- * to the Java input stream
- */
- if (0 < result) {
- return result;
- } else if (0 == result) {
- return -1;
- } else {
- // If EAGAIN or EWOULDBLOCK, read timed out
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- jniThrowException(env, "java/net/SocketTimeoutException",
- netLookupErrorString(SOCKERR_TIMEOUT));
- } else {
- int err = convertError(errno);
- throwSocketException(env, err);
- }
- return 0;
+ int rc = shutdown(fd, how);
+ if (rc == -1) {
+ jniThrowSocketException(env, errno);
}
}
-static jint osNetworkSystem_sendStreamImpl(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jbyteArray data, jint offset, jint count) {
- // LOGD("ENTER sendStreamImpl");
-
- int handle = 0;
- int result = 0, sent = 0;
-
- jboolean isCopy;
- jbyte *message = env->GetByteArrayElements(data, &isCopy);
-
- // Cap write length to available buf size
- int spaceAvailable = env->GetArrayLength(data) - offset;
- if (count > spaceAvailable) count = spaceAvailable;
-
- while (sent < count) {
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env,
- sent == 0 ? SOCKERR_BADSOCKET : SOCKERR_INTERRUPTED);
- env->ReleaseByteArrayElements(data, message, 0);
- return 0;
- }
-
- // LOGD("before select %d", count);
- selectWait(handle, SEND_RETRY_TIME, SELECT_WRITE_TYPE);
- result = send(handle, (jbyte *)message + offset + sent,
- (int) count - sent, SOCKET_NOFLAGS);
-
- if (result < 0) {
- result = errno;
- if (result == EAGAIN ||result == EWOULDBLOCK) {
- // LOGD("write blocked %d", sent);
- continue;
- }
- env->ReleaseByteArrayElements(data, message, 0);
- int err = convertError(result);
- throwSocketException(env, err);
- return 0;
- }
- sent += result;
- }
-
- env->ReleaseByteArrayElements(data, message, 0);
- return sent;
-}
-
-static void osNetworkSystem_shutdownInputImpl(JNIEnv* env, jobject obj,
+static void osNetworkSystem_shutdownInputImpl(JNIEnv* env, jobject,
jobject fileDescriptor) {
- // LOGD("ENTER shutdownInputImpl");
-
- int ret;
- int handle;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
- return;
- }
-
- ret = shutdown(handle, SHUT_RD);
-
- if (ret < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
- return;
- }
+ doShutdown(env, fileDescriptor, SHUT_RD);
}
-static void osNetworkSystem_shutdownOutputImpl(JNIEnv* env, jobject obj,
+static void osNetworkSystem_shutdownOutputImpl(JNIEnv* env, jobject,
jobject fileDescriptor) {
- // LOGD("ENTER shutdownOutputImpl");
-
- int ret;
- int handle;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- return;
- }
-
- ret = shutdown(handle, SHUT_WR);
-
- if (ret < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
- return;
- }
+ doShutdown(env, fileDescriptor, SHUT_WR);
}
static jint osNetworkSystem_sendDatagramImpl2(JNIEnv* env, jclass clazz,
- jobject fd, jbyteArray data, jint offset, jint length, jint port,
- jobject inetAddress) {
+ jobject fileDescriptor, jbyteArray data, jint offset, jint length,
+ jint port, jobject inetAddress) {
// LOGD("ENTER sendDatagramImpl2");
- jbyte *message;
- unsigned short nPort;
- int ret = 0, sent = 0;
- int handle = 0;
- struct sockaddr_storage sockaddrP;
-
+ sockaddr_storage sockAddr;
if (inetAddress != NULL) {
- ret = inetAddressToSocketAddress(env, inetAddress, port, &sockaddrP);
- if (ret < 0) // Exception has already been thrown.
- return 0;
-
- handle = jniGetFDFromFileDescriptor(env, fd);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
- return 0;
+ if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) {
+ return -1;
}
}
- message = (jbyte*) malloc(length * sizeof(jbyte));
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return 0;
+ }
+
+ jbyte* message = (jbyte*) malloc(length * sizeof(jbyte));
if (message == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError",
"couldn't allocate enough memory for readSocket");
@@ -2848,208 +2251,182 @@
env->GetByteArrayRegion(data, offset, length, message);
- while (sent < length) {
- handle = jniGetFDFromFileDescriptor(env, fd);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env,
- sent == 0 ? SOCKERR_BADDESC : SOCKERR_INTERRUPTED);
+ int totalBytesSent = 0;
+ while (totalBytesSent < length) {
+ ssize_t bytesSent = TEMP_FAILURE_RETRY(sendto(fd,
+ message + totalBytesSent, length - totalBytesSent,
+ SOCKET_NOFLAGS,
+ reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr)));
+ if (bytesSent == -1) {
+ jniThrowSocketException(env, errno);
free(message);
return 0;
}
- ssize_t result;
- do {
- result = sendto(handle, (char *) (message + sent),
- (int) (length - sent), SOCKET_NOFLAGS,
- (struct sockaddr *) &sockaddrP, sizeof(sockaddrP));
- } while (result < 0 && errno == EINTR);
- if (result < 0) {
- int err = convertError(errno);
- throwSocketException(env, err);
- free(message);
- return 0;
- }
-
- sent += result;
+ totalBytesSent += bytesSent;
}
free(message);
- return sent;
+ return totalBytesSent;
}
-static jint osNetworkSystem_selectImpl(JNIEnv* env, jclass clazz,
- jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC,
- jint countWriteC, jintArray outFlags, jlong timeout) {
- // LOGD("ENTER selectImpl");
-
- struct timeval timeP;
- int result = 0;
- int size = 0;
- jobject gotFD;
- fd_set *fdset_read,*fdset_write;
- int handle;
- jboolean isCopy ;
- jint *flagArray;
- int val;
- unsigned int time_sec = (unsigned int)timeout/1000;
- unsigned int time_msec = (unsigned int)(timeout%1000);
-
- fdset_read = (fd_set *)malloc(sizeof(fd_set));
- fdset_write = (fd_set *)malloc(sizeof(fd_set));
-
- FD_ZERO(fdset_read);
- FD_ZERO(fdset_write);
-
- for (val = 0; val<countReadC; val++) {
-
- gotFD = env->GetObjectArrayElement(readFDArray,val);
-
- handle = jniGetFDFromFileDescriptor(env, gotFD);
-
- FD_SET(handle, fdset_read);
-
- if (0 > (size - handle)) {
- size = handle;
+static bool initFdSet(JNIEnv* env, jobjectArray fdArray, jint count, fd_set* fdSet, int* maxFd) {
+ for (int i = 0; i < count; ++i) {
+ jobject fileDescriptor = env->GetObjectArrayElement(fdArray, i);
+ if (fileDescriptor == NULL) {
+ return false;
+ }
+
+ const int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ if (fd < 0 || fd > 1024) {
+ LOGE("selectImpl: ignoring invalid fd %i", fd);
+ continue;
+ }
+
+ FD_SET(fd, fdSet);
+
+ if (fd > *maxFd) {
+ *maxFd = fd;
}
}
+ return true;
+}
- for (val = 0; val<countWriteC; val++) {
-
- gotFD = env->GetObjectArrayElement(writeFDArray,val);
-
- handle = jniGetFDFromFileDescriptor(env, gotFD);
-
- FD_SET(handle, fdset_write);
-
- if (0 > (size - handle)) {
- size = handle;
+/*
+ * Note: fdSet has to be non-const because although on Linux FD_ISSET() is sane
+ * and takes a const fd_set*, it takes fd_set* on Mac OS. POSIX is not on our
+ * side here:
+ * http://www.opengroup.org/onlinepubs/000095399/functions/select.html
+ */
+static bool translateFdSet(JNIEnv* env, jobjectArray fdArray, jint count, fd_set& fdSet, jint* flagArray, size_t offset, jint op) {
+ for (int i = 0; i < count; ++i) {
+ jobject fileDescriptor = env->GetObjectArrayElement(fdArray, i);
+ if (fileDescriptor == NULL) {
+ return false;
}
- }
+
+ const int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+ const bool valid = fd >= 0 && fd < 1024;
- /* the size is the max_fd + 1 */
- size =size + 1;
-
- if (0 > size) {
- result = SOCKERR_FDSET_SIZEBAD;
- } else {
- /* only set when timeout >= 0 (non-block)*/
- if (0 <= timeout) {
-
- timeP.tv_sec = time_sec;
- timeP.tv_usec = time_msec*1000;
-
- result = sockSelect(size, fdset_read, fdset_write, NULL, &timeP);
-
+ if (valid && FD_ISSET(fd, &fdSet)) {
+ flagArray[i + offset] = op;
} else {
- result = sockSelect(size, fdset_read, fdset_write, NULL, NULL);
+ flagArray[i + offset] = SOCKET_OP_NONE;
}
}
+ return true;
+}
- if (0 < result) {
- /*output the result to a int array*/
- flagArray = env->GetIntArrayElements(outFlags, &isCopy);
-
- for (val=0; val<countReadC; val++) {
- gotFD = env->GetObjectArrayElement(readFDArray,val);
-
- handle = jniGetFDFromFileDescriptor(env, gotFD);
-
- if (FD_ISSET(handle,fdset_read)) {
- flagArray[val] = SOCKET_OP_READ;
- } else {
- flagArray[val] = SOCKET_OP_NONE;
- }
- }
-
- for (val=0; val<countWriteC; val++) {
-
- gotFD = env->GetObjectArrayElement(writeFDArray,val);
-
- handle = jniGetFDFromFileDescriptor(env, gotFD);
-
- if (FD_ISSET(handle,fdset_write)) {
- flagArray[val+countReadC] = SOCKET_OP_WRITE;
- } else {
- flagArray[val+countReadC] = SOCKET_OP_NONE;
- }
- }
-
- env->ReleaseIntArrayElements(outFlags, flagArray, 0);
+static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass clazz,
+ jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC,
+ jint countWriteC, jintArray outFlags, jlong timeoutMs) {
+ // LOGD("ENTER selectImpl");
+
+ // Initialize the fd_sets.
+ int maxFd = -1;
+ fd_set readFds;
+ fd_set writeFds;
+ FD_ZERO(&readFds);
+ FD_ZERO(&writeFds);
+ bool initialized = initFdSet(env, readFDArray, countReadC, &readFds, &maxFd) &&
+ initFdSet(env, writeFDArray, countWriteC, &writeFds, &maxFd);
+ if (!initialized) {
+ return -1;
}
-
- free(fdset_write);
- free(fdset_read);
-
- /* return both correct and error result, let java handle the exception*/
- return result;
+
+ // Initialize the timeout, if any.
+ timeval tv;
+ timeval* tvp = NULL;
+ if (timeoutMs >= 0) {
+ tv = toTimeval(timeoutMs);
+ tvp = &tv;
+ }
+
+ // Perform the select.
+ int result = select(maxFd + 1, &readFds, &writeFds, NULL, tvp);
+ if (result == 0) {
+ // Timeout.
+ return JNI_FALSE;
+ } else if (result == -1) {
+ // Error.
+ if (errno == EINTR) {
+ return JNI_FALSE;
+ } else {
+ jniThrowSocketException(env, errno);
+ return JNI_FALSE;
+ }
+ }
+
+ // Translate the result into the int[] we're supposed to fill in.
+ jint* flagArray = env->GetIntArrayElements(outFlags, NULL);
+ if (flagArray == NULL) {
+ return JNI_FALSE;
+ }
+ bool okay = translateFdSet(env, readFDArray, countReadC, readFds, flagArray, 0, SOCKET_OP_READ) &&
+ translateFdSet(env, writeFDArray, countWriteC, writeFds, flagArray, countReadC, SOCKET_OP_WRITE);
+ env->ReleaseIntArrayElements(outFlags, flagArray, 0);
+ return okay;
}
static jobject osNetworkSystem_getSocketLocalAddressImpl(JNIEnv* env,
- jclass clazz, jobject fileDescriptor, jboolean preferIPv6Addresses) {
+ jclass, jobject fileDescriptor, jboolean preferIPv6Addresses) {
// LOGD("ENTER getSocketLocalAddressImpl");
- struct sockaddr_storage addr;
- socklen_t addrLen = sizeof(addr);
-
- memset(&addr, 0, addrLen);
-
-
- int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_UNKNOWNSOCKET);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
return NULL;
}
- int result;
- result = getsockname(handle, (struct sockaddr *)&addr, &addrLen);
-
- // Spec says ignore all errors
+ sockaddr_storage addr;
+ socklen_t addrLen = sizeof(addr);
+ memset(&addr, 0, addrLen);
+ int rc = getsockname(fd, (sockaddr*) &addr, &addrLen);
+ if (rc == -1) {
+ // TODO: the public API doesn't allow failure, so this whole method
+ // represents a broken design. In practice, though, getsockname can't
+ // fail unless we give it invalid arguments.
+ LOGE("getsockname failed: %s (errno=%i)", strerror(errno), errno);
+ return NULL;
+ }
return socketAddressToInetAddress(env, &addr);
}
-static jint osNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass,
jobject fileDescriptor, jboolean preferIPv6Addresses) {
// LOGD("ENTER getSocketLocalPortImpl");
- struct sockaddr_storage addr;
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
+ return 0;
+ }
+
+ sockaddr_storage addr;
socklen_t addrLen = sizeof(addr);
-
- int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- int result;
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_UNKNOWNSOCKET);
+ memset(&addr, 0, addrLen);
+ int rc = getsockname(fd, (sockaddr*) &addr, &addrLen);
+ if (rc == -1) {
+ // TODO: the public API doesn't allow failure, so this whole method
+ // represents a broken design. In practice, though, getsockname can't
+ // fail unless we give it invalid arguments.
+ LOGE("getsockname failed: %s (errno=%i)", strerror(errno), errno);
return 0;
}
-
- result = getsockname(handle, (struct sockaddr *)&addr, &addrLen);
-
- if (0 != result) {
- // The java spec does not indicate any exceptions on this call
- return 0;
- } else {
- return getSocketAddressPort(&addr);
- }
+ return getSocketAddressPort(&addr);
}
static jobject osNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz,
jobject fileDescriptor, jint anOption) {
// LOGD("ENTER getSocketOptionImpl");
- int handle;
int intValue = 0;
socklen_t intSize = sizeof(int);
- unsigned char byteValue = 0;
- socklen_t byteSize = sizeof(unsigned char);
int result;
struct sockaddr_storage sockVal;
socklen_t sockSize = sizeof(sockVal);
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
- return NULL;
+ int handle;
+ if (!jniGetFd(env, fileDescriptor, handle)) {
+ return 0;
}
switch ((int) anOption & 0xffff) {
@@ -3058,7 +2435,7 @@
socklen_t size = sizeof(struct linger);
result = getsockopt(handle, SOL_SOCKET, SO_LINGER, &lingr, &size);
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return NULL;
}
if (!lingr.l_onoff) {
@@ -3068,17 +2445,95 @@
}
return newJavaLangInteger(env, intValue);
}
+
case JAVASOCKOPT_TCP_NODELAY: {
if ((anOption >> 16) & BROKEN_TCP_NODELAY) {
return NULL;
}
result = getsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &intValue, &intSize);
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return NULL;
}
return newJavaLangBoolean(env, intValue);
}
+
+ case JAVASOCKOPT_SO_SNDBUF: {
+ result = getsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intValue, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangInteger(env, intValue);
+ }
+
+ case JAVASOCKOPT_SO_RCVBUF: {
+ result = getsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intValue, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangInteger(env, intValue);
+ }
+
+ case JAVASOCKOPT_SO_BROADCAST: {
+ result = getsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intValue, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+
+ case JAVASOCKOPT_SO_REUSEADDR: {
+ result = getsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intValue, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+
+ case JAVASOCKOPT_SO_KEEPALIVE: {
+ result = getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intValue, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+
+ case JAVASOCKOPT_SO_OOBINLINE: {
+ result = getsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intValue, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangBoolean(env, intValue);
+ }
+
+ case JAVASOCKOPT_IP_TOS: {
+ result = getOrSetSocketOption(SOCKOPT_GET, handle, IP_TOS,
+ IPV6_TCLASS, &intValue, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangInteger(env, intValue);
+ }
+
+ case JAVASOCKOPT_SO_RCVTIMEOUT: {
+ struct timeval timeout;
+ socklen_t size = sizeof(timeout);
+ result = getsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout, &size);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return NULL;
+ }
+ return newJavaLangInteger(env, toMs(timeout));
+ }
+
+#ifdef ENABLE_MULTICAST
case JAVASOCKOPT_MCAST_TTL: {
if ((anOption >> 16) & BROKEN_MULTICAST_TTL) {
return newJavaLangByte(env, 0);
@@ -3088,137 +2543,86 @@
IPV6_MULTICAST_HOPS, &intValue,
&intSize);
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return NULL;
}
return newJavaLangByte(env, (jbyte)(intValue & 0xFF));
}
- case JAVASOCKOPT_MCAST_INTERFACE: {
+
+ case JAVASOCKOPT_IP_MULTICAST_IF: {
if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
return NULL;
}
- result = getsockopt(handle, SOL_IP, IP_MULTICAST_IF, &sockVal, &sockSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
+ result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF,
+ &sockVal, &sockSize);
+ if (result == -1) {
+ jniThrowSocketException(env, errno);
return NULL;
}
- // This option is IPv4-only.
- sockVal.ss_family = AF_INET;
+ if (sockVal.ss_family != AF_INET) {
+ // Java expects an AF_INET INADDR_ANY, but Linux just returns AF_UNSPEC.
+ jbyteArray inAddrAny = env->NewByteArray(4); // { 0, 0, 0, 0 }
+ return byteArrayToInetAddress(env, inAddrAny);
+ }
return socketAddressToInetAddress(env, &sockVal);
}
+
case JAVASOCKOPT_IP_MULTICAST_IF2: {
if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
return NULL;
}
struct ip_mreqn multicastRequest;
- int interfaceIndex;
+ int interfaceIndex = 0;
socklen_t optionLength;
int addressFamily = getSocketAddressFamily(handle);
switch (addressFamily) {
case AF_INET:
optionLength = sizeof(multicastRequest);
- result = getsockopt(handle, SOL_IP, IP_MULTICAST_IF,
+ result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF,
&multicastRequest, &optionLength);
if (result == 0)
interfaceIndex = multicastRequest.imr_ifindex;
break;
case AF_INET6:
optionLength = sizeof(interfaceIndex);
- result = getsockopt(handle, SOL_IPV6, IPV6_MULTICAST_IF,
+ result = getsockopt(handle, IPPROTO_IPV6, IPV6_MULTICAST_IF,
&interfaceIndex, &optionLength);
break;
default:
- throwSocketException(env, SOCKERR_BADAF);
+ jniThrowSocketException(env, EAFNOSUPPORT);
return NULL;
}
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return NULL;
}
-
return newJavaLangInteger(env, interfaceIndex);
}
- case JAVASOCKOPT_SO_SNDBUF: {
- result = getsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intValue, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangInteger(env, intValue);
- }
- case JAVASOCKOPT_SO_RCVBUF: {
- result = getsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intValue, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangInteger(env, intValue);
- }
- case JAVASOCKOPT_SO_BROADCAST: {
- result = getsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intValue, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangBoolean(env, intValue);
- }
- case JAVASOCKOPT_SO_REUSEADDR: {
- result = getsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intValue, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangBoolean(env, intValue);
- }
- case JAVASOCKOPT_SO_KEEPALIVE: {
- result = getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intValue, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangBoolean(env, intValue);
- }
- case JAVASOCKOPT_SO_OOBINLINE: {
- result = getsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intValue, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangBoolean(env, intValue);
- }
+
case JAVASOCKOPT_IP_MULTICAST_LOOP: {
result = getOrSetSocketOption(SOCKOPT_GET, handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP, &intValue,
&intSize);
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return NULL;
}
return newJavaLangBoolean(env, intValue);
}
- case JAVASOCKOPT_IP_TOS: {
- result = getOrSetSocketOption(SOCKOPT_GET, handle, IP_TOS,
- IPV6_TCLASS, &intValue, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangInteger(env, intValue);
+#else
+ case JAVASOCKOPT_MCAST_TTL:
+ case JAVASOCKOPT_IP_MULTICAST_IF:
+ case JAVASOCKOPT_IP_MULTICAST_IF2:
+ case JAVASOCKOPT_IP_MULTICAST_LOOP: {
+ jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
+ return NULL;
}
- case JAVASOCKOPT_SO_RCVTIMEOUT: {
- struct timeval timeout;
- socklen_t size = sizeof(timeout);
- result = getsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout, &size);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return NULL;
- }
- return newJavaLangInteger(env, timeout.tv_sec * 1000 + timeout.tv_usec/1000);
- }
+#endif // def ENABLE_MULTICAST
+
default: {
- throwSocketException(env, SOCKERR_OPTUNSUPP);
+ jniThrowSocketException(env, ENOPROTOOPT);
return NULL;
}
}
@@ -3229,11 +2633,9 @@
jobject fileDescriptor, jint anOption, jobject optVal) {
// LOGD("ENTER setSocketOptionImpl");
- int handle, result;
+ int result;
int intVal;
socklen_t intSize = sizeof(int);
- unsigned char byteVal;
- socklen_t byteSize = sizeof(unsigned char);
struct sockaddr_storage sockVal;
int sockSize = sizeof(sockVal);
@@ -3242,22 +2644,21 @@
} else if (env->IsInstanceOf(optVal, gCachedFields.boolean_class)) {
intVal = (int) env->GetBooleanField(optVal, gCachedFields.boolean_class_value);
} else if (env->IsInstanceOf(optVal, gCachedFields.byte_class)) {
- byteVal = (int) env->GetByteField(optVal, gCachedFields.byte_class_value);
+ // TTL uses a byte in Java, but the kernel still wants an int.
+ intVal = (int) env->GetByteField(optVal, gCachedFields.byte_class_value);
} else if (env->IsInstanceOf(optVal, gCachedFields.iaddr_class)) {
- if (inetAddressToSocketAddress(env, optVal, 0, &sockVal) < 0) {
- // Exception has already been thrown.
+ if (!inetAddressToSocketAddress(env, optVal, 0, &sockVal)) {
return;
}
} else if (env->IsInstanceOf(optVal, gCachedFields.genericipmreq_class)) {
// we'll use optVal directly
} else {
- throwSocketException(env, SOCKERR_OPTUNSUPP);
+ jniThrowSocketException(env, ENOPROTOOPT);
return;
}
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
+ int handle;
+ if (!jniGetFd(env, fileDescriptor, handle)) {
return;
}
@@ -3269,7 +2670,7 @@
result = setsockopt(handle, SOL_SOCKET, SO_LINGER, &lingr,
sizeof(struct linger));
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
break;
@@ -3281,23 +2682,106 @@
}
result = setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &intVal, intSize);
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
break;
}
+ case JAVASOCKOPT_SO_SNDBUF: {
+ result = setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intVal, intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_RCVBUF: {
+ result = setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intVal, intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_BROADCAST: {
+ result = setsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intVal, intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_REUSEADDR: {
+ result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+ case JAVASOCKOPT_SO_KEEPALIVE: {
+ result = setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intVal, intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_OOBINLINE: {
+ result = setsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intVal, intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_IP_TOS: {
+ result = getOrSetSocketOption(SOCKOPT_SET, handle, IP_TOS,
+ IPV6_TCLASS, &intVal, &intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_REUSEADDR_AND_REUSEPORT: {
+ // SO_REUSEPORT doesn't need to get set on this System
+ result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize);
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+ case JAVASOCKOPT_SO_RCVTIMEOUT: {
+ timeval timeout(toTimeval(intVal));
+ result = setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout,
+ sizeof(struct timeval));
+ if (0 != result) {
+ jniThrowSocketException(env, errno);
+ return;
+ }
+ break;
+ }
+
+#ifdef ENABLE_MULTICAST
case JAVASOCKOPT_MCAST_TTL: {
if ((anOption >> 16) & BROKEN_MULTICAST_TTL) {
return;
}
- // Java uses a byte to store the TTL, but the kernel uses an int.
- intVal = byteVal;
result = getOrSetSocketOption(SOCKOPT_SET, handle, IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS, &intVal,
&intSize);
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
break;
@@ -3315,24 +2799,24 @@
break;
}
- case JAVASOCKOPT_MCAST_INTERFACE: {
+ case JAVASOCKOPT_IP_MULTICAST_IF: {
if ((anOption >> 16) & BROKEN_MULTICAST_IF) {
return;
}
// This call is IPv4 only. The socket may be IPv6, but the address
// that identifies the interface to join must be an IPv4 address.
if (sockVal.ss_family != AF_INET) {
- throwSocketException(env, SOCKERR_BADAF);
+ jniThrowSocketException(env, EAFNOSUPPORT);
return;
}
struct ip_mreqn mcast_req;
memset(&mcast_req, 0, sizeof(mcast_req));
struct sockaddr_in *sin = (struct sockaddr_in *) &sockVal;
mcast_req.imr_address = sin->sin_addr;
- result = setsockopt(handle, SOL_IP, IP_MULTICAST_IF,
+ result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF,
&mcast_req, sizeof(mcast_req));
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
break;
@@ -3361,67 +2845,14 @@
optionLength = sizeof(interfaceIndex);
break;
default:
- throwSocketException(env, SOCKERR_BADAF);
+ jniThrowSocketException(env, EAFNOSUPPORT);
return;
}
result = getOrSetSocketOption(SOCKOPT_SET, handle,
IP_MULTICAST_IF, IPV6_MULTICAST_IF, optionValue,
&optionLength);
if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
-
- case JAVASOCKOPT_SO_SNDBUF: {
- result = setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intVal, intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
-
- case JAVASOCKOPT_SO_RCVBUF: {
- result = setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intVal, intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
-
- case JAVASOCKOPT_SO_BROADCAST: {
- result = setsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intVal, intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
-
- case JAVASOCKOPT_SO_REUSEADDR: {
- result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
- case JAVASOCKOPT_SO_KEEPALIVE: {
- result = setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intVal, intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
-
- case JAVASOCKOPT_SO_OOBINLINE: {
- result = setsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intVal, intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
break;
@@ -3433,47 +2864,25 @@
IPV6_MULTICAST_LOOP, &intVal,
&intSize);
if (0 != result) {
- throwSocketException(env, convertError(errno));
+ jniThrowSocketException(env, errno);
return;
}
break;
}
-
- case JAVASOCKOPT_IP_TOS: {
- result = getOrSetSocketOption(SOCKOPT_SET, handle, IP_TOS,
- IPV6_TCLASS, &intVal, &intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
+#else
+ case JAVASOCKOPT_MCAST_TTL:
+ case JAVASOCKOPT_MCAST_ADD_MEMBERSHIP:
+ case JAVASOCKOPT_MCAST_DROP_MEMBERSHIP:
+ case JAVASOCKOPT_IP_MULTICAST_IF:
+ case JAVASOCKOPT_IP_MULTICAST_IF2:
+ case JAVASOCKOPT_IP_MULTICAST_LOOP: {
+ jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
+ return;
}
-
- case JAVASOCKOPT_REUSEADDR_AND_REUSEPORT: {
- // SO_REUSEPORT doesn't need to get set on this System
- result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize);
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
-
- case JAVASOCKOPT_SO_RCVTIMEOUT: {
- struct timeval timeout;
- timeout.tv_sec = intVal / 1000;
- timeout.tv_usec = (intVal % 1000) * 1000;
- result = setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout,
- sizeof(struct timeval));
- if (0 != result) {
- throwSocketException(env, convertError(errno));
- return;
- }
- break;
- }
+#endif // def ENABLE_MULTICAST
default: {
- throwSocketException(env, SOCKERR_OPTUNSUPP);
+ jniThrowSocketException(env, ENOPROTOOPT);
}
}
}
@@ -3489,285 +2898,19 @@
jobject fileDescriptor) {
// LOGD("ENTER socketCloseImpl");
- int handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADSOCKET);
+ int fd;
+ if (!jniGetFd(env, fileDescriptor, fd)) {
return;
}
jniSetFileDescriptorOfFD(env, fileDescriptor, -1);
- close(handle);
+ close(fd);
}
-static void osNetworkSystem_setInetAddressImpl(JNIEnv* env, jobject obj,
- jobject sender, jbyteArray address) {
- // LOGD("ENTER setInetAddressImpl");
-
- env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address);
-}
-
-// TODO: rewrite this method in Java and make it support IPv6.
-static jobject osNetworkSystem_inheritedChannelImpl(JNIEnv* env, jobject obj) {
- // LOGD("ENTER inheritedChannelImpl");
-
- int socket = 0;
- int opt;
- socklen_t length = sizeof(opt);
- int socket_type;
- struct sockaddr_in local_addr;
- struct sockaddr_in remote_addr;
- jclass channel_class, socketaddr_class, serverSocket_class, socketImpl_class;
- jobject channel_object = NULL, socketaddr_object, serverSocket_object;
- jobject fd_object, addr_object, localAddr_object, socketImpl_object;
- jfieldID port_field, socketaddr_field, bound_field, fd_field;
- jfieldID serverSocket_field, socketImpl_field, addr_field, localAddr_field;
- jmethodID channel_new;
- jbyteArray addr_array;
- struct sockaddr_in *sock;
- jbyte * address;
- jbyte * localAddr;
- jboolean jtrue = JNI_TRUE;
-
- if (0 != getsockopt(socket, SOL_SOCKET, SO_TYPE, &opt, &length)) {
- return NULL;
- }
- if (SOCK_STREAM !=opt && SOCK_DGRAM !=opt) {
- return NULL;
- }
- socket_type = opt;
-
- length = sizeof(struct sockaddr);
- if (0 != getsockname(socket, (struct sockaddr *)&local_addr, &length)) {
- return NULL;
- } else {
- if (AF_INET != local_addr.sin_family || length != sizeof(struct sockaddr)) {
- return NULL;
- }
- localAddr = (jbyte*) malloc(sizeof(jbyte)*4);
- if (NULL == localAddr) {
- return NULL;
- }
- memcpy (localAddr, &(local_addr.sin_addr.s_addr), 4);
- }
- if (0 != getpeername(socket, (struct sockaddr *)&remote_addr, &length)) {
- remote_addr.sin_port = 0;
- remote_addr.sin_addr.s_addr = 0;
- address = (jbyte*) malloc(sizeof(jbyte)*4);
- bzero(address, sizeof(jbyte)*4);
- } else {
- if (AF_INET != remote_addr.sin_family
- || length != sizeof(struct sockaddr)) {
- return NULL;
- }
- address = (jbyte*) malloc(sizeof(jbyte)*4);
- memcpy (address, &(remote_addr.sin_addr.s_addr), 4);
- }
-
- // analysis end, begin pack to java
- if (SOCK_STREAM == opt) {
- if (remote_addr.sin_port!=0) {
- //socket
- channel_class = env->FindClass(
- "org/apache/harmony/nio/internal/SocketChannelImpl");
- if (NULL == channel_class) {
- goto clean;
- }
-
- channel_new = env->GetMethodID(channel_class, "<init>", "()V");
- if (NULL == channel_new) {
- goto clean;
- }
- channel_object = env->NewObject(channel_class, channel_new);
- if (NULL == channel_object) {
- goto clean;
- }
- // new and set FileDescript
-
- fd_field = env->GetFieldID(channel_class, "fd",
- "java/io/FielDescriptor");
- fd_object = env->GetObjectField(channel_object, fd_field);
- if (NULL == fd_object) {
- goto clean;
- }
-
- jniSetFileDescriptorOfFD(env, fd_object, socket);
-
- // local port
- port_field = env->GetFieldID(channel_class, "localPort", "I");
- env->SetIntField(channel_object, port_field,
- ntohs(local_addr.sin_port));
-
- // new and set remote addr
- addr_array = env->NewByteArray((jsize)4);
- env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, address);
- addr_object = env->NewObject(gCachedFields.i4addr_class,
- gCachedFields.i4addr_class_init, addr_array);
- if (NULL == addr_object) {
- goto clean;
- }
- socketaddr_class = env->FindClass("java/net/InetSocketAddress");
- socketaddr_field = env->GetFieldID(channel_class, "connectAddress",
- "Ljava/net/InetSocketAddress;");
- socketaddr_object = env->GetObjectField(channel_object,
- socketaddr_field);
- if (NULL == socketaddr_object) {
- goto clean;
- }
-
- // localAddr
- socketaddr_class = env->FindClass("java/net/InetSocketAddress");
- socketaddr_field = env->GetFieldID(channel_class, "connectAddress",
- "Ljava/net/InetSocketAddress;");
- socketaddr_object = env->GetObjectField(channel_object,
- socketaddr_field);
-
- localAddr_field = env->GetFieldID(channel_class, "localAddress",
- "Ljava/net/Inet4Address;");
- addr_array = env->NewByteArray((jsize)4);
- env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, localAddr);
- localAddr_object = env->NewObject(gCachedFields.i4addr_class,
- gCachedFields.i4addr_class_init, addr_array);
- jfieldID socketaddr_field = env->GetFieldID(channel_class,
- "connectAddress", "Ljava/net/InetSocketAddress;");
- jobject socketaddr_object = env->GetObjectField(channel_object,
- socketaddr_field);
- env->SetObjectField(socketaddr_object, localAddr_field,
- localAddr_object);
- if (NULL == localAddr_object) {
- goto clean;
- }
-
-
- // set port
- port_field = env->GetFieldID(socketaddr_class, "port", "I");
- env->SetIntField(socketaddr_object, port_field,
- ntohs(remote_addr.sin_port));
-
- // set bound
- if (0 != local_addr.sin_port) {
- bound_field = env->GetFieldID(channel_class, "isBound", "Z");
- env->SetBooleanField(channel_object, bound_field, jtrue);
- }
-
- } else {
- //serverSocket
- channel_class = env->FindClass(
- "org/apache/harmony/nio/internal/ServerSocketChannelImpl");
- if (NULL == channel_class) {
- goto clean;
- }
-
- channel_new = env->GetMethodID(channel_class, "<init>", "()V");
- if (NULL == channel_new) {
- goto clean;
- }
- channel_object = env->NewObject(channel_class, channel_new);
- if (NULL == channel_object) {
- goto clean;
- }
-
- serverSocket_field = env->GetFieldID(channel_class, "socket",
- "Ljava/net/ServerSocket;");
- serverSocket_class = env->FindClass("Ljava/net/ServerSocket;");
- serverSocket_object = env->GetObjectField(channel_object,
- serverSocket_field);
- // set bound
- if (0 != local_addr.sin_port) {
- bound_field = env->GetFieldID(channel_class, "isBound", "Z");
- env->SetBooleanField(channel_object, bound_field, jtrue);
- bound_field = env->GetFieldID(serverSocket_class, "isBound", "Z");
- env->SetBooleanField(serverSocket_object, bound_field, jtrue);
- }
- // localAddr
- socketImpl_class = env->FindClass("java/net/SocketImpl");
- socketImpl_field = env->GetFieldID(channel_class, "impl",
- "Ljava/net/SocketImpl;");
- socketImpl_object = env->GetObjectField(channel_object,
- socketImpl_field);
- if (NULL == socketImpl_object) {
- goto clean;
- }
-
- addr_array = env->NewByteArray((jsize)4);
- localAddr_field = env->GetFieldID(channel_class, "localAddress",
- "Ljava/net/InetAddress;");
- memset(address, 0, 4);
- env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, address);
- localAddr_object = env->NewObject(gCachedFields.i4addr_class,
- gCachedFields.i4addr_class_init, addr_array);
- if (NULL == localAddr_object) {
- goto clean;
- }
- env->SetObjectField(socketImpl_object, localAddr_field,
- localAddr_object);
- addr_array = env->NewByteArray((jsize)4);
- env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, localAddr);
- env->SetObjectField(localAddr_object,
- gCachedFields.iaddr_ipaddress, addr_array);
-
- // set port
- port_field = env->GetFieldID(socketImpl_class, "localport", "I");
- env->SetIntField(socketImpl_object, port_field,
- ntohs(local_addr.sin_port));
- }
- } else {
- //Datagram Socket
- // new DatagramChannel
- channel_class = env->FindClass(
- "org/apache/harmony/nio/internal/DatagramChannelImpl");
- if (NULL == channel_class) {
- goto clean;
- }
-
- channel_new = env->GetMethodID(channel_class, "<init>", "()V");
- if (NULL == channel_new) {
- goto clean;
- }
- channel_object = env->NewObject(channel_class, channel_new);
- if (NULL == channel_object) {
- goto clean;
- }
-
- // new and set FileDescript
- fd_field = env->GetFieldID(channel_class, "fd", "java/io/FileDescriptor");
- fd_object = env->GetObjectField(channel_object, fd_field);
- if (NULL == fd_object) {
- goto clean;
- }
-
- jniSetFileDescriptorOfFD(env, fd_object, socket);
-
- port_field = env->GetFieldID(channel_class, "localPort", "I");
- env->SetIntField(channel_object, port_field, ntohs(local_addr.sin_port));
-
- // new and set remote addr
- addr_array = env->NewByteArray((jsize)4);
- env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, address);
- addr_object = env->NewObject(gCachedFields.iaddr_class,
- gCachedFields.i4addr_class_init, addr_array);
- if (NULL == addr_object) {
- goto clean;
- }
- socketaddr_class = env->FindClass("java/net/InetSocketAddress");
- socketaddr_field = env->GetFieldID(channel_class, "connectAddress",
- "Ljava/net/InetSocketAddress;");
- socketaddr_object = env->GetObjectField(channel_object, socketaddr_field);
- if (NULL == socketaddr_object) {
- goto clean;
- }
-
- // set bound
- if (0 != local_addr.sin_port) {
- bound_field = env->GetFieldID(channel_class, "isBound", "Z");
- env->SetBooleanField(channel_object, bound_field, jtrue);
- }
- }
-clean:
- free(address);
- free(localAddr);
- return channel_object;
+static jobject osNetworkSystem_inheritedChannel(JNIEnv* env, jobject obj) {
+ // Android never has stdin/stdout connected to a socket.
+ return NULL;
}
/*
@@ -3779,11 +2922,10 @@
{ "createStreamSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createStreamSocketImpl },
{ "createDatagramSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createDatagramSocketImpl },
{ "readSocketImpl", "(Ljava/io/FileDescriptor;[BIII)I", (void*) osNetworkSystem_readSocketImpl },
- { "readSocketDirectImpl", "(Ljava/io/FileDescriptor;IIII)I", (void*) osNetworkSystem_readSocketDirectImpl },
+ { "readSocketDirectImpl", "(Ljava/io/FileDescriptor;III)I", (void*) osNetworkSystem_readSocketDirectImpl },
{ "writeSocketImpl", "(Ljava/io/FileDescriptor;[BII)I", (void*) osNetworkSystem_writeSocketImpl },
{ "writeSocketDirectImpl", "(Ljava/io/FileDescriptor;III)I", (void*) osNetworkSystem_writeSocketDirectImpl },
{ "setNonBlockingImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_setNonBlockingImpl },
- { "connectSocketImpl", "(Ljava/io/FileDescriptor;ILjava/net/InetAddress;I)I", (void*) osNetworkSystem_connectSocketImpl },
{ "connectWithTimeoutSocketImpl", "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;II[B)I", (void*) osNetworkSystem_connectWithTimeoutSocketImpl },
{ "connectStreamWithTimeoutSocketImpl","(Ljava/io/FileDescriptor;IIILjava/net/InetAddress;)V", (void*) osNetworkSystem_connectStreamWithTimeoutSocketImpl },
{ "socketBindImpl", "(Ljava/io/FileDescriptor;ILjava/net/InetAddress;)V", (void*) osNetworkSystem_socketBindImpl },
@@ -3804,12 +2946,10 @@
{ "sendConnectedDatagramImpl", "(Ljava/io/FileDescriptor;[BIIZ)I", (void*) osNetworkSystem_sendConnectedDatagramImpl },
{ "sendConnectedDatagramDirectImpl", "(Ljava/io/FileDescriptor;IIIZ)I", (void*) osNetworkSystem_sendConnectedDatagramDirectImpl },
{ "createServerStreamSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createServerStreamSocketImpl },
- { "receiveStreamImpl", "(Ljava/io/FileDescriptor;[BIII)I", (void*) osNetworkSystem_receiveStreamImpl },
- { "sendStreamImpl", "(Ljava/io/FileDescriptor;[BII)I", (void*) osNetworkSystem_sendStreamImpl },
{ "shutdownInputImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_shutdownInputImpl },
{ "shutdownOutputImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_shutdownOutputImpl },
{ "sendDatagramImpl2", "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I", (void*) osNetworkSystem_sendDatagramImpl2 },
- { "selectImpl", "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)I", (void*) osNetworkSystem_selectImpl },
+ { "selectImpl", "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)Z", (void*) osNetworkSystem_selectImpl },
{ "getSocketLocalAddressImpl", "(Ljava/io/FileDescriptor;Z)Ljava/net/InetAddress;", (void*) osNetworkSystem_getSocketLocalAddressImpl },
{ "getSocketLocalPortImpl", "(Ljava/io/FileDescriptor;Z)I", (void*) osNetworkSystem_getSocketLocalPortImpl },
{ "getSocketOptionImpl", "(Ljava/io/FileDescriptor;I)Ljava/lang/Object;", (void*) osNetworkSystem_getSocketOptionImpl },
@@ -3817,7 +2957,7 @@
{ "getSocketFlagsImpl", "()I", (void*) osNetworkSystem_getSocketFlagsImpl },
{ "socketCloseImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_socketCloseImpl },
{ "setInetAddressImpl", "(Ljava/net/InetAddress;[B)V", (void*) osNetworkSystem_setInetAddressImpl },
- { "inheritedChannelImpl", "()Ljava/nio/channels/Channel;", (void*) osNetworkSystem_inheritedChannelImpl },
+ { "inheritedChannel", "()Ljava/nio/channels/Channel;", (void*) osNetworkSystem_inheritedChannel },
{ "byteArrayToIpString", "([B)Ljava/lang/String;", (void*) osNetworkSystem_byteArrayToIpString },
{ "ipStringToByteArray", "(Ljava/lang/String;)[B", (void*) osNetworkSystem_ipStringToByteArray },
};
diff --git a/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c b/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
index e92b776..80f2bee 100644
--- a/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
+++ b/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
@@ -229,7 +229,6 @@
jfloat result;
numBits = highestSetBitHighPrecision (f, length) + 1;
- numBits -= lowestSetBitHighPrecision (f, length);
if (numBits < 25 && e >= 0 && e < LOG5_OF_TWO_TO_THE_N)
{
return ((jfloat) LOW_I32_FROM_PTR (f)) * tenToTheE (e);
@@ -240,7 +239,7 @@
}
else if (e >= 0 && e < 39)
{
- result = (jfloat) (toDoubleHighPrecision (f, length) * pow (10.0, e));
+ result = (jfloat) (toDoubleHighPrecision (f, length) * pow (10.0, (double) e));
}
else if (e >= 39)
{
@@ -260,7 +259,7 @@
int dexp;
U_32 fmant, fovfl;
U_64 dmant;
- dresult = toDoubleHighPrecision (f, length) / pow (10.0, -e);
+ dresult = toDoubleHighPrecision (f, length) / pow (10.0, (double) -e);
if (IS_DENORMAL_DBL (dresult))
{
FLOAT_TO_INTBITS (result) = 0;
@@ -606,4 +605,3 @@
"org/apache/harmony/luni/util/FloatingPointParser",
gMethods, NELEM(gMethods));
}
-
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index d277f82..184a13d 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -13,7 +13,7 @@
java_lang_Math.c \
java_lang_StrictMath.c \
java_net_InetAddress.cpp \
- java_net_NetworkInterface.c \
+ java_net_NetworkInterface.cpp \
cbigint.c \
commonDblParce.c \
org_apache_harmony_luni_util_fltparse.c \
diff --git a/luni/src/test/java/com/google/coretests/CoreTestRunner.java b/luni/src/test/java/com/google/coretests/CoreTestRunner.java
index d469c86..ad766aa 100644
--- a/luni/src/test/java/com/google/coretests/CoreTestRunner.java
+++ b/luni/src/test/java/com/google/coretests/CoreTestRunner.java
@@ -15,6 +15,8 @@
*/
package com.google.coretests;
+import java.util.ArrayList;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -67,6 +69,11 @@
private int fTimeout;
private int fStep = 1;
+
+ /**
+ * The path to write XML reports to, or {@code null} for no reports.
+ */
+ private String xmlReportsDirectory;
/**
* Creates a new instance of our CoreTestRunner.
@@ -125,19 +132,32 @@
* Make sure the original suite is unreachable after we have
* created the new one, so GC can dispose terminated tests.
*/
- suite = new CoreTestSuite(suite, fFlags, fStep, null);
-
- return super.doRun(suite, wait);
+ CoreTestSuite coreTestSuite = new CoreTestSuite(suite, fFlags, fStep, null);
+
+ XmlReportPrinter xmlReportPrinter = xmlReportsDirectory != null
+ ? new XmlReportPrinter(coreTestSuite)
+ : null;
+
+ TestResult result = super.doRun(coreTestSuite, wait);
+
+ if (xmlReportPrinter != null) {
+ System.out.print("Printing XML Reports... ");
+ xmlReportPrinter.setResults(result);
+ int numFiles = xmlReportPrinter.generateReports(xmlReportsDirectory);
+ System.out.println(numFiles + " files written.");
+ }
+
+ return result;
}
-
+
/**
* Prints a help screen on the console.
*/
private void showHelp() {
- System.out.println("Usage: run-core-tests {<param>} <test>");
+ System.out.println("Usage: run-core-tests [OPTION]... [TEST]...");
System.out.println();
- System.out.println("Where <test> is a class name, optionally followed");
- System.out.println("by \"#\" and a method name, and <param> is one of");
+ System.out.println("Where each TEST is a class name, optionally followed");
+ System.out.println("by \"#\" and a method name, and each OPTION is one of");
System.out.println("the following:");
System.out.println();
System.out.println(" --include-all");
@@ -160,6 +180,7 @@
System.out.println(" --isolate-all");
System.out.println(" --isolate-none");
System.out.println(" --verbose");
+ System.out.println(" --xml-reports-directory <path>");
System.out.println(" --help");
System.out.println();
System.out.println("Default parameters are:");
@@ -185,26 +206,29 @@
}
/**
- * Tries to create a Test instance from a given string. The string might
+ * Tries to create a Test instance from the given strings. The strings might
* either specify a class only or a class plus a method name, separated by
* a "#".
*/
- private Test createTest(String testCase) throws Exception {
- int p = testCase.indexOf("#");
- if (p != -1) {
- String testName = testCase.substring(p + 1);
- testCase = testCase.substring(0, p);
-
- return TestSuite.createTest(Class.forName(testCase), testName);
- } else {
- return getTest(testCase);
+ private Test createTest(List<String> testCases) throws Exception {
+ TestSuite result = new TestSuite();
+ for (String testCase : testCases) {
+ int p = testCase.indexOf("#");
+ if (p != -1) {
+ String testName = testCase.substring(p + 1);
+ testCase = testCase.substring(0, p);
+
+ result.addTest(TestSuite.createTest(Class.forName(testCase), testName));
+ } else {
+ result.addTest(getTest(testCase));
+ }
}
-
+ return result;
}
@Override
protected TestResult start(String args[]) throws Exception {
- String testName = null;
+ List<String> testNames = new ArrayList<String>();
// String victimName = null;
boolean wait = false;
@@ -265,16 +289,18 @@
// victimName = args[++i];
} else if (args[i].equals("--dry-run")) {
fFlags = fFlags | CoreTestSuite.DRY_RUN;
+ } else if (args[i].equals("--xml-reports-directory")) {
+ xmlReportsDirectory = args[++i];
} else if (args[i].equals("--help")) {
showHelp();
System.exit(1);
} else {
- System.err.println("Unknown argument " + args[i] +
- ", try --help");
- System.exit(1);
+ unknownArgument(args[i]);
}
+ } else if (args[i].startsWith("-")) {
+ unknownArgument(args[i]);
} else {
- testName = args[i];
+ testNames.add(args[i]);
}
}
@@ -288,7 +314,7 @@
System.out.println();
try {
- return doRun(createTest(testName), wait);
+ return doRun(createTest(testNames), wait);
}
catch(Exception e) {
e.printStackTrace();
@@ -296,4 +322,8 @@
}
}
+ private static void unknownArgument(String arg) {
+ System.err.println("Unknown argument " + arg + ", try --help");
+ System.exit(1);
+ }
}
diff --git a/luni/src/test/java/com/google/coretests/CoreTestSuite.java b/luni/src/test/java/com/google/coretests/CoreTestSuite.java
index 3c9e7fa..fd7531f 100644
--- a/luni/src/test/java/com/google/coretests/CoreTestSuite.java
+++ b/luni/src/test/java/com/google/coretests/CoreTestSuite.java
@@ -98,6 +98,8 @@
public static final int REVERSE = 512;
public static final int DRY_RUN = 1024;
+
+ private final String name;
/**
* The total number of tests in the original suite.
@@ -154,7 +156,8 @@
*/
public CoreTestSuite(Test suite, int flags, int step, TestCase victim) {
super();
-
+
+ name = suite.toString();
fStep = step;
addAndFlatten(suite, flags);
fVictim = victim;
@@ -180,17 +183,13 @@
}
}
} else if (test instanceof TestCase) {
- TestCase caze = (TestCase)test;
+ TestCase testCase = (TestCase)test;
boolean ignoreMe = false;
- boolean isAndroidOnly = hasAnnotation(caze,
- AndroidOnly.class);
- boolean isBrokenTest = hasAnnotation(caze,
- BrokenTest.class);
- boolean isKnownFailure = hasAnnotation(caze,
- KnownFailure.class);
- boolean isSideEffect = hasAnnotation(caze,
- SideEffect.class);
+ boolean isAndroidOnly = hasAnnotation(testCase, AndroidOnly.class);
+ boolean isBrokenTest = hasAnnotation(testCase, BrokenTest.class);
+ boolean isKnownFailure = hasAnnotation(testCase, KnownFailure.class);
+ boolean isSideEffect = hasAnnotation(testCase, SideEffect.class);
boolean isNormalTest =
!(isAndroidOnly || isBrokenTest || isKnownFailure ||
isSideEffect);
@@ -269,27 +268,27 @@
public void run(TestResult result) {
// Run tests
int i = 0;
-
+
while (fTests.size() != 0 && !result.shouldStop()) {
TestCase test = (TestCase)fTests.elementAt(i);
Thread.currentThread().setContextClassLoader(
test.getClass().getClassLoader());
-
+
test.run(result);
/*
if (fVictim != null) {
TestResult dummy = fVictim.run();
-
+
if (dummy.failureCount() != 0) {
result.addError(fTests.elementAt(i), new RuntimeException(
- "Probable side effect",
+ "Probable side effect",
((TestFailure)dummy.failures().nextElement()).
thrownException()));
} else if (dummy.errorCount() != 0) {
result.addError(fTests.elementAt(i), new RuntimeException(
- "Probable side effect",
+ "Probable side effect",
((TestFailure)dummy.errors().nextElement()).
thrownException()));
}
@@ -352,4 +351,7 @@
return fTests.size();
}
+ @Override public String toString() {
+ return name;
+ }
}
diff --git a/luni/src/test/java/com/google/coretests/Main.java b/luni/src/test/java/com/google/coretests/Main.java
index 1dcebc5..4a91a95 100644
--- a/luni/src/test/java/com/google/coretests/Main.java
+++ b/luni/src/test/java/com/google/coretests/Main.java
@@ -27,7 +27,7 @@
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Running all tests...");
- TestRunner.run(AllTests.suite());
+ CoreTestRunner.main(new String[] { "tests.AllTests" });
} else if ("--stats".equals(args[0])) {
// Delegate to new stats test runner
String[] args2 = new String[args.length - 1];
diff --git a/luni/src/test/java/com/google/coretests/XmlReportPrinter.java b/luni/src/test/java/com/google/coretests/XmlReportPrinter.java
new file mode 100644
index 0000000..315371f
--- /dev/null
+++ b/luni/src/test/java/com/google/coretests/XmlReportPrinter.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.google.coretests;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestFailure;
+import junit.framework.TestResult;
+import junit.runner.BaseTestRunner;
+import org.kxml2.io.KXmlSerializer;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+
+/**
+ * Writes JUnit results to a series of XML files in a format consistent with
+ * Ant's XMLJUnitResultFormatter.
+ *
+ * <p>Unlike Ant's formatter, this class does not report the execution time of
+ * tests.
+ */
+public class XmlReportPrinter {
+
+ private static final String TESTSUITE = "testsuite";
+ private static final String TESTCASE = "testcase";
+ private static final String ERROR = "error";
+ private static final String FAILURE = "failure";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_TIME = "time";
+ private static final String ATTR_ERRORS = "errors";
+ private static final String ATTR_FAILURES = "failures";
+ private static final String ATTR_TESTS = "tests";
+ private static final String ATTR_TYPE = "type";
+ private static final String ATTR_MESSAGE = "message";
+ private static final String PROPERTIES = "properties";
+ private static final String ATTR_CLASSNAME = "classname";
+ private static final String TIMESTAMP = "timestamp";
+ private static final String HOSTNAME = "hostname";
+
+ /** the XML namespace */
+ private static final String ns = null;
+
+ /** the test suites, which each contain tests */
+ private final Map<String, Suite> suites = new LinkedHashMap<String, Suite>();
+
+ /**
+ * Create a report printer that prints the specified test suite. Since the
+ * CoreTestSuite nulls-out tests after they're run (to limit memory
+ * consumption), it is necessary to create the report printer prior to test
+ * execution.
+ */
+ public XmlReportPrinter(CoreTestSuite allTests) {
+ // partition the tests by suite to be consistent with Ant's printer
+ for (Enumeration<Test> e = allTests.tests(); e.hasMoreElements(); ) {
+ TestId test = new TestId(e.nextElement());
+
+ // create the suite's entry in the map if necessary
+ Suite suite = suites.get(test.className);
+ if (suite == null) {
+ suite = new Suite(test.className);
+ suites.put(test.className, suite);
+ }
+
+ suite.tests.add(test);
+ }
+ }
+
+ public void setResults(TestResult result) {
+ populateFailures(true, result.errors());
+ populateFailures(false, result.failures());
+ }
+
+ /**
+ * Populate the list of failures in each of the suites.
+ */
+ private void populateFailures(boolean errors, Enumeration<TestFailure> failures) {
+ while (failures.hasMoreElements()) {
+ TestFailure failure = failures.nextElement();
+ TestId test = new TestId(failure.failedTest());
+ Suite suite = suites.get(test.className);
+
+ if (suite == null) {
+ throw new IllegalStateException( "received a failure for a "
+ + "test that wasn't in the original test suite!");
+ }
+
+ if (errors) {
+ suite.errors.put(test, failure);
+ } else {
+ suite.failures.put(test, failure);
+ }
+ }
+ }
+
+ public int generateReports(String directory) {
+ File parent = new File(directory);
+ parent.mkdirs();
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ TimeZone gmt = TimeZone.getTimeZone("GMT");
+ dateFormat.setTimeZone(gmt);
+ dateFormat.setLenient(true);
+ String timestamp = dateFormat.format(new Date());
+
+ for (Suite suite : suites.values()) {
+ FileOutputStream stream = null;
+ try {
+ stream = new FileOutputStream(new File(parent, "TEST-" + suite.name + ".xml"));
+
+ KXmlSerializer serializer = new KXmlSerializer();
+ serializer.setOutput(stream, "UTF-8");
+ serializer.startDocument("UTF-8", null);
+ serializer.setFeature(
+ "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ suite.print(serializer, timestamp);
+ serializer.endDocument();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ }
+
+ return suites.size();
+ }
+
+ static class Suite {
+ private final String name;
+ private final List<TestId> tests = new ArrayList<TestId>();
+ private final Map<TestId, TestFailure> failures = new HashMap<TestId, TestFailure>();
+ private final Map<TestId, TestFailure> errors = new HashMap<TestId, TestFailure>();
+
+ Suite(String name) {
+ this.name = name;
+ }
+
+ void print(KXmlSerializer serializer, String timestamp) throws IOException {
+ serializer.startTag(ns, TESTSUITE);
+ serializer.attribute(ns, ATTR_NAME, name);
+ serializer.attribute(ns, ATTR_TESTS, Integer.toString(tests.size()));
+ serializer.attribute(ns, ATTR_FAILURES, Integer.toString(failures.size()));
+ serializer.attribute(ns, ATTR_ERRORS, Integer.toString(errors.size()));
+ serializer.attribute(ns, ATTR_TIME, "0");
+
+ serializer.attribute(ns, TIMESTAMP, timestamp);
+ serializer.attribute(ns, HOSTNAME, "localhost");
+ serializer.startTag(ns, PROPERTIES);
+ serializer.endTag(ns, PROPERTIES);
+
+ for (TestId testId : tests) {
+ TestFailure error = errors.get(testId);
+ TestFailure failure = failures.get(testId);
+
+ if (error != null) {
+ testId.printFailure(serializer, ERROR, error.thrownException());
+ } else if (failure != null) {
+ testId.printFailure(serializer, FAILURE, failure.thrownException());
+ } else {
+ testId.printSuccess(serializer);
+ }
+ }
+
+ serializer.endTag(ns, TESTSUITE);
+ }
+ }
+
+ private static class TestId {
+ private final String name;
+ private final String className;
+
+ TestId(Test test) {
+ this.name = test instanceof TestCase
+ ? ((TestCase) test).getName()
+ : test.toString();
+ this.className = test.getClass().getName();
+ }
+
+ void printSuccess(KXmlSerializer serializer) throws IOException {
+ serializer.startTag(ns, TESTCASE);
+ printAttributes(serializer);
+ serializer.endTag(ns, TESTCASE);
+ }
+
+ void printFailure(KXmlSerializer serializer, String type, Throwable t)
+ throws IOException {
+ serializer.startTag(ns, TESTCASE);
+ printAttributes(serializer);
+
+ serializer.startTag(ns, type);
+ String message = t.getMessage();
+ if (message != null && message.length() > 0) {
+ serializer.attribute(ns, ATTR_MESSAGE, t.getMessage());
+ }
+ serializer.attribute(ns, ATTR_TYPE, t.getClass().getName());
+ serializer.text(BaseTestRunner.getFilteredTrace(t));
+ serializer.endTag(ns, type);
+
+ serializer.endTag(ns, TESTCASE);
+ }
+
+ void printAttributes(KXmlSerializer serializer) throws IOException {
+ serializer.attribute(ns, ATTR_NAME, name);
+ serializer.attribute(ns, ATTR_CLASSNAME, className);
+ serializer.attribute(ns, ATTR_TIME, "0");
+ }
+
+ @Override public boolean equals(Object o) {
+ return o instanceof TestId
+ && ((TestId) o).name.equals(name)
+ && ((TestId) o).className.equals(className);
+ }
+
+ @Override public int hashCode() {
+ return name.hashCode() ^ className.hashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/luni/src/test/java/java/lang/AllTests.java b/luni/src/test/java/java/lang/AllTests.java
new file mode 100644
index 0000000..a40ef3a
--- /dev/null
+++ b/luni/src/test/java/java/lang/AllTests.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static final Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(java.lang.FloatTest.class);
+ suite.addTestSuite(java.lang.ProcessBuilderTest.class);
+ return suite;
+ }
+}
diff --git a/luni/src/test/java/java/lang/FloatTest.java b/luni/src/test/java/java/lang/FloatTest.java
new file mode 100644
index 0000000..bd8c197
--- /dev/null
+++ b/luni/src/test/java/java/lang/FloatTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class FloatTest extends junit.framework.TestCase {
+ public void test_valueOf_String1() throws Exception {
+ // This threw OutOfMemoryException.
+ // http://code.google.com/p/android/issues/detail?id=4185
+ assertEquals(2358.166016f, Float.valueOf("2358.166016"));
+ }
+ public void test_valueOf_String2() throws Exception {
+ // This threw OutOfMemoryException.
+ // http://code.google.com/p/android/issues/detail?id=3156
+ assertEquals(-2.14748365E9f, Float.valueOf(String.valueOf(Integer.MIN_VALUE)));
+ }
+}
diff --git a/luni/src/test/java/java/lang/ProcessBuilderTest.java b/luni/src/test/java/java/lang/ProcessBuilderTest.java
new file mode 100644
index 0000000..53acf01
--- /dev/null
+++ b/luni/src/test/java/java/lang/ProcessBuilderTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import static tests.support.Support_Exec.execAndCheckOutput;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.io.InputStream;
+import java.util.Arrays;
+
+public class ProcessBuilderTest extends junit.framework.TestCase {
+ private static String shell() {
+ return "Dalvik".equals(System.getProperty("java.vm.name")) ? "/system/bin/sh" : "/bin/sh";
+ }
+
+ public void testRedirectErrorStream(boolean doRedirect,
+ String expectedOut, String expectedErr) throws Exception {
+ ProcessBuilder pb = new ProcessBuilder(shell(), "-c", "echo out; echo err 1>&2");
+ pb.redirectErrorStream(doRedirect);
+ execAndCheckOutput(pb, expectedOut, expectedErr);
+ }
+
+ public void test_redirectErrorStream_true() throws Exception {
+ testRedirectErrorStream(true, "out\nerr\n", "");
+ }
+
+ public void test_redirectErrorStream_false() throws Exception {
+ testRedirectErrorStream(false, "out\n", "err\n");
+ }
+}
diff --git a/luni/src/test/java/java/net/AllTests.java b/luni/src/test/java/java/net/AllTests.java
new file mode 100644
index 0000000..6d26f0d
--- /dev/null
+++ b/luni/src/test/java/java/net/AllTests.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static final Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(java.net.SocketTest.class);
+ return suite;
+ }
+}
diff --git a/luni/src/test/java/java/net/SocketTest.java b/luni/src/test/java/java/net/SocketTest.java
new file mode 100644
index 0000000..b0e278f
--- /dev/null
+++ b/luni/src/test/java/java/net/SocketTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class SocketTest extends junit.framework.TestCase {
+ /**
+ * Our getLocalAddress and getLocalPort currently use getsockname(3).
+ * This means they give incorrect results on closed sockets (as well
+ * as requiring an unnecessary call into native code).
+ */
+ public void test_getLocalAddress_after_close() throws Exception {
+ Socket s = new Socket();
+ try {
+ // Bind to an ephemeral local port.
+ s.bind(new InetSocketAddress("localhost", 0));
+ assertTrue(s.getLocalAddress().isLoopbackAddress());
+ // What local port did we get?
+ int localPort = s.getLocalPort();
+ assertTrue(localPort > 0);
+ // Now close the socket...
+ s.close();
+ // The RI returns the ANY address but the original local port after close.
+ assertTrue(s.getLocalAddress().isAnyLocalAddress());
+ assertEquals(localPort, s.getLocalPort());
+ } finally {
+ s.close();
+ }
+ }
+}
diff --git a/luni/src/test/java/java/nio/charset/AllTests.java b/luni/src/test/java/java/nio/charset/AllTests.java
new file mode 100644
index 0000000..6f45162
--- /dev/null
+++ b/luni/src/test/java/java/nio/charset/AllTests.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.nio.charset;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static final Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(java.nio.charset.CharsetDecoderTest.class);
+ return suite;
+ }
+}
diff --git a/luni/src/test/java/java/nio/charset/CharsetDecoderTest.java b/luni/src/test/java/java/nio/charset/CharsetDecoderTest.java
new file mode 100644
index 0000000..23184dd
--- /dev/null
+++ b/luni/src/test/java/java/nio/charset/CharsetDecoderTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.nio.charset;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CharsetDecoderTest extends junit.framework.TestCase {
+ private static final String CHARSET = "UTF-16";
+
+ private static final String SAMPLE_STRING = "Android";
+
+ // http://code.google.com/p/android/issues/detail?id=4237
+ public void test_ByteArray_decode_no_offset() throws Exception {
+ CharsetDecoder decoder = getCharsetDecoderUnderTest();
+ byte[] arr = getEncodedByteArrayFixture();
+ ByteBuffer inBuffer = ByteBuffer.wrap(arr, 0, arr.length).slice();
+ CharBuffer outBuffer = CharBuffer.allocate(arr.length);
+ decoder.reset();
+ CoderResult coderResult = decoder.decode(inBuffer, outBuffer, true);
+ assertFalse(coderResult.toString(), coderResult.isError());
+ decoder.flush(outBuffer);
+ outBuffer.flip();
+ assertEquals(SAMPLE_STRING, outBuffer.toString().trim());
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=4237
+ public void test_ByteArray_decode_with_offset() throws Exception {
+ CharsetDecoder decoder = getCharsetDecoderUnderTest();
+ byte[] arr = getEncodedByteArrayFixture();
+ arr = prependByteToByteArray(arr, new Integer(1).byteValue());
+ int offset = 1;
+ ByteBuffer inBuffer = ByteBuffer.wrap(arr, offset, arr.length - offset).slice();
+ CharBuffer outBuffer = CharBuffer.allocate(arr.length - offset);
+ decoder.reset();
+ CoderResult coderResult = decoder.decode(inBuffer, outBuffer, true);
+ assertFalse(coderResult.toString(), coderResult.isError());
+ decoder.flush(outBuffer);
+ outBuffer.flip();
+ assertEquals(SAMPLE_STRING, outBuffer.toString().trim());
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=4237
+ public void test_ByteArray_decode_with_offset_using_facade_method() throws Exception {
+ CharsetDecoder decoder = getCharsetDecoderUnderTest();
+ byte[] arr = getEncodedByteArrayFixture();
+ arr = prependByteToByteArray(arr, new Integer(1).byteValue());
+ int offset = 1;
+ CharBuffer outBuffer = decoder.decode(ByteBuffer.wrap(arr, offset, arr.length - offset));
+ assertEquals(SAMPLE_STRING, outBuffer.toString().trim());
+ }
+
+ private static byte[] prependByteToByteArray(byte[] arr, byte b) {
+ byte[] result = new byte[arr.length + 1];
+ result[0] = b;
+ System.arraycopy(arr, 0, result, 1, arr.length);
+ return result;
+ }
+
+ private static CharsetDecoder getCharsetDecoderUnderTest() {
+ return Charset.forName(CHARSET).newDecoder();
+ }
+
+ private byte[] getEncodedByteArrayFixture() throws CharacterCodingException {
+ CharsetEncoder encoder = Charset.forName(CHARSET).newEncoder();
+ return encoder.encode(CharBuffer.wrap(SAMPLE_STRING)).array();
+ }
+}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
index c99a0c1..e26cf74 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
@@ -20,11 +20,22 @@
import dalvik.annotation.AndroidOnly;
import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+import junit.framework.TestCase;
+import tests.util.TestEnvironment;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -41,22 +52,16 @@
import java.net.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
-import java.net.SocketTimeoutException;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.Arrays;
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManagerFactory;
-
-import junit.framework.TestCase;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
/**
* Implementation independent test for HttpsURLConnection.
@@ -95,19 +100,6 @@
// Proxy authentication required response code
private static final int AUTHENTICATION_REQUIRED_CODE = 407;
- // fields keeping the system values of corresponding properties
- private static String systemKeyStoreType;
-
- private static String systemKeyStore;
-
- private static String systemKeyStorePassword;
-
- private static String systemTrustStoreType;
-
- private static String systemTrustStore;
-
- private static String systemTrustStorePassword;
-
private static File store;
static {
@@ -132,19 +124,14 @@
// set up the properties defining the default values needed by SSL stuff
setUpStoreProperties();
- try {
- SSLSocketFactory defaultSSLSF = HttpsURLConnection
- .getDefaultSSLSocketFactory();
- ServerSocket ss = new ServerSocket(0);
- Socket s = defaultSSLSF
- .createSocket("localhost", ss.getLocalPort());
- ss.accept();
- s.close();
- ss.close();
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ SSLSocketFactory defaultSSLSF = HttpsURLConnection
+ .getDefaultSSLSocketFactory();
+ ServerSocket ss = new ServerSocket(0);
+ Socket s = defaultSSLSF
+ .createSocket("localhost", ss.getLocalPort());
+ ss.accept();
+ s.close();
+ ss.close();
}
/**
@@ -167,33 +154,28 @@
// set up the properties defining the default values needed by SSL stuff
setUpStoreProperties();
- try {
- // create the SSL server socket acting as a server
- SSLContext ctx = getContext();
- ServerSocket ss = ctx.getServerSocketFactory()
- .createServerSocket(0);
+ // create the SSL server socket acting as a server
+ SSLContext ctx = getContext();
+ ServerSocket ss = ctx.getServerSocketFactory()
+ .createServerSocket(0);
- // create the HostnameVerifier to check hostname verification
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create the HostnameVerifier to check hostname verification
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
- // create url connection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection();
+ // create url connection to be tested
+ URL url = new URL("https://localhost:" + ss.getLocalPort());
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection();
- // perform the interaction between the peers
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
+ // perform the interaction between the peers
+ SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- // check the connection state
- checkConnectionStateParameters(connection, peerSocket);
+ // check the connection state
+ checkConnectionStateParameters(connection, peerSocket);
- // should silently exit
- connection.connect();
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ // should silently exit
+ connection.connect();
}
/**
@@ -227,37 +209,32 @@
// set up the properties defining the default values needed by SSL stuff
setUpStoreProperties();
+ // create the SSL server socket acting as a server
+ SSLContext ctx = getContext();
+ ServerSocket ss = ctx.getServerSocketFactory()
+ .createServerSocket(0);
+
+ // create the HostnameVerifier to check hostname verification
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+
+ // create url connection to be tested
+ URL url = new URL("https://localhost:" + ss.getLocalPort());
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection();
+
try {
- // create the SSL server socket acting as a server
- SSLContext ctx = getContext();
- ServerSocket ss = ctx.getServerSocketFactory()
- .createServerSocket(0);
-
- // create the HostnameVerifier to check hostname verification
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
-
- // create url connection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection();
-
- try {
- doInteraction(connection, ss, NOT_FOUND_CODE);
- fail("Expected exception was not thrown.");
- } catch (FileNotFoundException e) {
- if (DO_LOG) {
- System.out.println("Expected exception was thrown: "
- + e.getMessage());
- }
+ doInteraction(connection, ss, NOT_FOUND_CODE);
+ fail("Expected exception was not thrown.");
+ } catch (FileNotFoundException e) {
+ if (DO_LOG) {
+ System.out.println("Expected exception was thrown: "
+ + e.getMessage());
}
-
- // should silently exit
- connection.connect();
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
}
+
+ // should silently exit
+ connection.connect();
}
/**
@@ -454,39 +431,34 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
- try {
- // create the SSLServerSocket which will be used by server side
- SSLServerSocket ss = (SSLServerSocket) getContext()
- .getServerSocketFactory().createServerSocket(0);
+ // create the SSLServerSocket which will be used by server side
+ SSLServerSocket ss = (SSLServerSocket) getContext()
+ .getServerSocketFactory().createServerSocket(0);
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
- // create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection();
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://localhost:" + ss.getLocalPort());
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection();
- TestHostnameVerifier hnv_late = new TestHostnameVerifier();
- // replace default verifier
- connection.setHostnameVerifier(hnv_late);
+ TestHostnameVerifier hnv_late = new TestHostnameVerifier();
+ // replace default verifier
+ connection.setHostnameVerifier(hnv_late);
- // perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- assertTrue("Hostname verification was not done", hnv_late.verified);
- assertFalse(
- "Hostname verification should not be done by this verifier",
- hnv.verified);
- checkConnectionStateParameters(connection, peerSocket);
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
+ assertTrue("Hostname verification was not done", hnv_late.verified);
+ assertFalse(
+ "Hostname verification should not be done by this verifier",
+ hnv.verified);
+ checkConnectionStateParameters(connection, peerSocket);
- // should silently exit
- connection.connect();
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ // should silently exit
+ connection.connect();
}
/**
@@ -505,32 +477,27 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
- try {
- // create the SSLServerSocket which will be used by server side
- SSLServerSocket ss = (SSLServerSocket) getContext()
- .getServerSocketFactory().createServerSocket(0);
+ // create the SSLServerSocket which will be used by server side
+ SSLServerSocket ss = (SSLServerSocket) getContext()
+ .getServerSocketFactory().createServerSocket(0);
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
- // create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection();
- connection.setDoOutput(true);
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://localhost:" + ss.getLocalPort());
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection();
+ connection.setDoOutput(true);
- // perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
+ checkConnectionStateParameters(connection, peerSocket);
- // should silently exit
- connection.connect();
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ // should silently exit
+ connection.connect();
}
/**
@@ -562,32 +529,27 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
- try {
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ // create the SSLServerSocket which will be used by server side
+ ServerSocket ss = new ServerSocket(0);
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
- // create HttpsURLConnection to be tested
- URL url = new URL("https://requested.host:55556/requested.data");
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost", ss
- .getLocalPort())));
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://requested.host:55556/requested.data");
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection(new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress("localhost", ss
+ .getLocalPort())));
- // perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
+ checkConnectionStateParameters(connection, peerSocket);
- // should silently exit
- connection.connect();
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ // should silently exit
+ connection.connect();
}
/**
@@ -620,40 +582,35 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
- try {
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ // create the SSLServerSocket which will be used by server side
+ ServerSocket ss = new ServerSocket(0);
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
- Authenticator.setDefault(new Authenticator() {
+ Authenticator.setDefault(new Authenticator() {
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("user", "password"
- .toCharArray());
- }
- });
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication("user", "password"
+ .toCharArray());
+ }
+ });
- // create HttpsURLConnection to be tested
- URL url = new URL("https://requested.host:55555/requested.data");
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost", ss
- .getLocalPort())));
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://requested.host:55555/requested.data");
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection(new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress("localhost", ss
+ .getLocalPort())));
- // perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
+ checkConnectionStateParameters(connection, peerSocket);
- // should silently exit
- connection.connect();
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ // should silently exit
+ connection.connect();
}
/**
@@ -688,40 +645,35 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
- try {
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ // create the SSLServerSocket which will be used by server side
+ ServerSocket ss = new ServerSocket(0);
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
- // create HttpsURLConnection to be tested
- URL url = new URL("https://requested.host:55555/requested.data");
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost", ss
- .getLocalPort())));
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://requested.host:55555/requested.data");
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection(new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress("localhost", ss
+ .getLocalPort())));
- // perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss);
+ checkConnectionStateParameters(connection, peerSocket);
- // create another SSLServerSocket which will be used by server side
- ss = new ServerSocket(0);
+ // create another SSLServerSocket which will be used by server side
+ ss = new ServerSocket(0);
- connection = (HttpsURLConnection) url.openConnection(new Proxy(
- Proxy.Type.HTTP, new InetSocketAddress("localhost", ss
- .getLocalPort())));
+ connection = (HttpsURLConnection) url.openConnection(new Proxy(
+ Proxy.Type.HTTP, new InetSocketAddress("localhost", ss
+ .getLocalPort())));
- // perform the interaction between the peers and check the results
- peerSocket = (SSLSocket) doInteraction(connection, ss);
- checkConnectionStateParameters(connection, peerSocket);
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ // perform the interaction between the peers and check the results
+ peerSocket = (SSLSocket) doInteraction(connection, ss);
+ checkConnectionStateParameters(connection, peerSocket);
}
/**
@@ -761,39 +713,34 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
- try {
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
+ // create the SSLServerSocket which will be used by server side
+ ServerSocket ss = new ServerSocket(0);
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
- Authenticator.setDefault(new Authenticator() {
+ Authenticator.setDefault(new Authenticator() {
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("user", "password"
- .toCharArray());
- }
- });
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication("user", "password"
+ .toCharArray());
+ }
+ });
- // create HttpsURLConnection to be tested
- URL url = new URL("https://requested.host:55554/requested.data");
- HttpsURLConnection connection = (HttpsURLConnection) url
- .openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost", ss
- .getLocalPort())));
- connection.setDoOutput(true);
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://requested.host:55554/requested.data");
+ HttpsURLConnection connection = (HttpsURLConnection) url
+ .openConnection(new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress("localhost", ss
+ .getLocalPort())));
+ connection.setDoOutput(true);
- // perform the interaction between the peers and check the results
- SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss,
- OK_CODE, true);
- checkConnectionStateParameters(connection, peerSocket);
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
- }
+ // perform the interaction between the peers and check the results
+ SSLSocket peerSocket = (SSLSocket) doInteraction(connection, ss,
+ OK_CODE, true);
+ checkConnectionStateParameters(connection, peerSocket);
}
/**
@@ -826,36 +773,31 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
+ // create the SSLServerSocket which will be used by server side
+ ServerSocket ss = new ServerSocket(0);
+
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://requested.host:55555/requested.data");
+ HttpURLConnection connection = (HttpURLConnection) url
+ .openConnection(new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress("localhost", ss
+ .getLocalPort())));
+
+ // perform the interaction between the peers and check the results
try {
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
-
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
-
- // create HttpsURLConnection to be tested
- URL url = new URL("https://requested.host:55555/requested.data");
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost", ss
- .getLocalPort())));
-
- // perform the interaction between the peers and check the results
- try {
- doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE,
- true);
- } catch (IOException e) {
- // SSL Tunnelling failed
- if (DO_LOG) {
- System.out.println("Got expected IOException: "
- + e.getMessage());
- }
+ doInteraction(connection, ss, AUTHENTICATION_REQUIRED_CODE,
+ true);
+ } catch (IOException e) {
+ // SSL Tunnelling failed
+ if (DO_LOG) {
+ System.out.println("Got expected IOException: "
+ + e.getMessage());
}
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
}
}
@@ -889,34 +831,29 @@
// setting up the properties pointing to the key/trust stores
setUpStoreProperties();
+ // create the SSLServerSocket which will be used by server side
+ ServerSocket ss = new ServerSocket(0);
+
+ // create the HostnameVerifier to check that Hostname verification
+ // is done
+ TestHostnameVerifier hnv = new TestHostnameVerifier();
+ HttpsURLConnection.setDefaultHostnameVerifier(hnv);
+
+ // create HttpsURLConnection to be tested
+ URL url = new URL("https://localhost:" + ss.getLocalPort());
+ HttpURLConnection connection = (HttpURLConnection) url
+ .openConnection(new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress("localhost", ss
+ .getLocalPort())));
+
try {
- // create the SSLServerSocket which will be used by server side
- ServerSocket ss = new ServerSocket(0);
-
- // create the HostnameVerifier to check that Hostname verification
- // is done
- TestHostnameVerifier hnv = new TestHostnameVerifier();
- HttpsURLConnection.setDefaultHostnameVerifier(hnv);
-
- // create HttpsURLConnection to be tested
- URL url = new URL("https://localhost:" + ss.getLocalPort());
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection(new Proxy(Proxy.Type.HTTP,
- new InetSocketAddress("localhost", ss
- .getLocalPort())));
-
- try {
- doInteraction(connection, ss, NOT_FOUND_CODE); // NOT FOUND
- fail("Expected exception was not thrown.");
- } catch (FileNotFoundException e) {
- if (DO_LOG) {
- System.out.println("Expected exception was thrown: "
- + e.getMessage());
- }
+ doInteraction(connection, ss, NOT_FOUND_CODE); // NOT FOUND
+ fail("Expected exception was not thrown.");
+ } catch (FileNotFoundException e) {
+ if (DO_LOG) {
+ System.out.println("Expected exception was thrown: "
+ + e.getMessage());
}
- } finally {
- // roll the properties back to system values
- tearDownStoreProperties();
}
}
@@ -928,6 +865,9 @@
* Log the name of the test case to be executed.
*/
public void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+
if (DO_LOG) {
System.out.println();
System.out.println("------------------------");
@@ -955,6 +895,7 @@
}
public void tearDown() {
+ TestEnvironment.reset();
if (store != null) {
store.delete();
}
@@ -994,7 +935,7 @@
* Returns the file name of the key/trust store. The key store file
* (named as "key_store." + extension equals to the default KeyStore
* type installed in the system in lower case) is searched in classpath.
- * @throws AssertionFailedError if property was not set
+ * @throws junit.framework.AssertionFailedError if property was not set
* or file does not exist.
*/
private static String getKeyStoreFileName() {
@@ -1038,17 +979,6 @@
private static void setUpStoreProperties() throws Exception {
String type = KeyStore.getDefaultType();
- systemKeyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
- systemKeyStore = System.getProperty("javax.net.ssl.keyStore");
- systemKeyStorePassword = System
- .getProperty("javax.net.ssl.keyStorePassword");
-
- systemTrustStoreType = System
- .getProperty("javax.net.ssl.trustStoreType");
- systemTrustStore = System.getProperty("javax.net.ssl.trustStore");
- systemTrustStorePassword = System
- .getProperty("javax.net.ssl.trustStorePassword");
-
System.setProperty("javax.net.ssl.keyStoreType", type);
System.setProperty("javax.net.ssl.keyStore", getKeyStoreFileName());
System.setProperty("javax.net.ssl.keyStorePassword", KS_PASSWORD);
@@ -1059,48 +989,6 @@
}
/**
- * Rolls back the values of system properties.
- */
- private static void tearDownStoreProperties() {
- if (systemKeyStoreType == null) {
- System.clearProperty("javax.net.ssl.keyStoreType");
- } else {
- System
- .setProperty("javax.net.ssl.keyStoreType",
- systemKeyStoreType);
- }
- if (systemKeyStore == null) {
- System.clearProperty("javax.net.ssl.keyStore");
- } else {
- System.setProperty("javax.net.ssl.keyStore", systemKeyStore);
- }
- if (systemKeyStorePassword == null) {
- System.clearProperty("javax.net.ssl.keyStorePassword");
- } else {
- System.setProperty("javax.net.ssl.keyStorePassword",
- systemKeyStorePassword);
- }
-
- if (systemTrustStoreType == null) {
- System.clearProperty("javax.net.ssl.trustStoreType");
- } else {
- System.setProperty("javax.net.ssl.trustStoreType",
- systemTrustStoreType);
- }
- if (systemTrustStore == null) {
- System.clearProperty("javax.net.ssl.trustStore");
- } else {
- System.setProperty("javax.net.ssl.trustStore", systemTrustStore);
- }
- if (systemTrustStorePassword == null) {
- System.clearProperty("javax.net.ssl.trustStorePassword");
- } else {
- System.setProperty("javax.net.ssl.trustStorePassword",
- systemTrustStorePassword);
- }
- }
-
- /**
* Performs interaction between client's HttpURLConnection and
* servers side (ServerSocket).
*/
@@ -1145,28 +1033,19 @@
ClientConnectionWork client = new ClientConnectionWork(clientConnection);
- server.start();
- client.start();
+ ExecutorService executorService = Executors.newFixedThreadPool(2);
+ try {
+ Future<Void> serverFuture = executorService.submit(server);
+ Future<Void> clientFuture = executorService.submit(client);
- client.join();
- server.join();
+ serverFuture.get(30, TimeUnit.SECONDS);
+ clientFuture.get(30, TimeUnit.SECONDS);
+ } catch (ExecutionException e) {
+ throw e.getCause();
+ } finally {
+ executorService.shutdown();
+ }
- if (client.thrown != null) {
- if (responseCode != OK_CODE) { // not OK response expected
- // it is probably expected exception, keep it as is
- throw client.thrown;
- }
- if ((client.thrown instanceof SocketTimeoutException)
- && (server.thrown != null)) {
- // server's exception is more informative in this case
- throw new Exception(server.thrown);
- } else {
- throw new Exception(client.thrown);
- }
- }
- if (server.thrown != null) {
- throw server.thrown;
- }
return server.peerSocket;
}
@@ -1190,7 +1069,7 @@
/**
* The base class for mock Client and Server.
*/
- static class Work extends Thread {
+ static class Work {
/**
* The header of OK HTTP response.
@@ -1242,11 +1121,6 @@
static final String clientsData = "_.-^ Client's Data ^-._";
/**
- * The exception thrown during peers interaction.
- */
- protected Throwable thrown;
-
- /**
* The print stream used for debug log.
* If it is null debug info will not be printed.
*/
@@ -1257,7 +1131,7 @@
*/
public synchronized void log(String message) {
if (DO_LOG && (out != null)) {
- System.out.println("[" + getName() + "]: " + message);
+ out.println("[" + this + "]: " + message);
}
}
}
@@ -1265,7 +1139,7 @@
/**
* The class used for server side works.
*/
- static class ServerWork extends Work {
+ static class ServerWork extends Work implements Callable<Void> {
// the server socket used for connection
private ServerSocket serverSocket;
@@ -1314,7 +1188,6 @@
this.actAsProxy = true;
}
this.actAsProxy = !(serverSocket instanceof SSLServerSocket);
- setName(this.actAsProxy ? "Proxy Server" : "Server");
}
/**
@@ -1337,7 +1210,7 @@
* If some exception occurs during the work it will be
* stored in the <code>thrown</code> field.
*/
- public void run() {
+ public Void call() throws Exception {
// the buffer used for reading the messages
byte[] buff = new byte[2048];
// the number of bytes read into the buffer
@@ -1371,14 +1244,13 @@
assertEquals(clientsData, message);
}
// just send the response
- os
- .write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
- .getBytes());
+ os.write(("HTTP/1.1 " + responseCode + "\n" + httpsResponseTail)
+ .getBytes());
os.flush();
os.close();
// and return
log("Work is DONE !actAsProxy");
- return;
+ return null;
}
// Do proxy work
@@ -1389,7 +1261,7 @@
// read response
num = is.read(buff);
if (num == -1) {
- // this connection was closed,
+ // this connection was closed,
// do clean up and create new one:
closeSocket(peerSocket);
peerSocket = serverSocket.accept();
@@ -1455,11 +1327,7 @@
.getBytes());
}
log("Work is DONE actAsProxy");
- } catch (Throwable e) {
- if (DO_LOG) {
- e.printStackTrace();
- }
- thrown = e;
+ return null;
} finally {
closeSocket(peerSocket);
try {
@@ -1467,13 +1335,17 @@
} catch (IOException e) {}
}
}
+
+ @Override public String toString() {
+ return actAsProxy ? "Proxy Server" : "Server";
+ }
}
/**
* The class used for client side works. It could be used to test
* both HttpURLConnection and HttpsURLConnection.
*/
- static class ClientConnectionWork extends Work {
+ static class ClientConnectionWork extends Work implements Callable<Void> {
// connection to be used to contact the server side
private HttpURLConnection connection;
@@ -1484,7 +1356,6 @@
*/
public ClientConnectionWork(HttpURLConnection connection) {
this.connection = connection;
- setName("Client Connection");
log("Created over connection: " + connection.getClass());
}
@@ -1493,42 +1364,41 @@
* If some exception occurs during the work it will be
* stored in the <code>thrown<code> field.
*/
- public void run() {
- try {
- log("Opening the connection..");
- connection.connect();
- log("Connection has been ESTABLISHED, using proxy: "
- + connection.usingProxy());
- if (connection.getDoOutput()) {
- // connection configured to post data, do so
- connection.getOutputStream().write(clientsData.getBytes());
- }
- // read the content of HTTP(s) response
- InputStream is = connection.getInputStream();
- log("Input Stream obtained");
- byte[] buff = new byte[2048];
- int num = 0;
- int byt = 0;
- while ((num < buff.length) && (is.available() > 0)
- && ((byt = is.read()) != -1)) {
- buff[num++] = (byte) byt;
- }
- String message = new String(buff, 0, num);
- log("Got content:\n" + message);
- log("------------------");
- log("Response code: " + connection.getResponseCode());
-
- if (connection instanceof HttpsURLConnection) {
- assertEquals(httpsResponseContent, message);
- } else {
- assertEquals(plainResponseContent, message);
- }
- } catch (Throwable e) {
- if (DO_LOG) {
- e.printStackTrace();
- }
- thrown = e;
+ public Void call() throws Exception {
+ log("Opening the connection..");
+ connection.connect();
+ log("Connection has been ESTABLISHED, using proxy: "
+ + connection.usingProxy());
+ if (connection.getDoOutput()) {
+ // connection configured to post data, do so
+ connection.getOutputStream().write(clientsData.getBytes());
}
+ // read the content of HTTP(s) response
+ InputStream is = connection.getInputStream();
+ log("Input Stream obtained");
+ byte[] buff = new byte[2048];
+ int num = 0;
+ int byt = 0;
+ while ((num < buff.length) && (is.available() > 0)
+ && ((byt = is.read()) != -1)) {
+ buff[num++] = (byte) byt;
+ }
+ String message = new String(buff, 0, num);
+ log("Got content:\n" + message);
+ log("------------------");
+ log("Response code: " + connection.getResponseCode());
+
+ if (connection instanceof HttpsURLConnection) {
+ assertEquals(httpsResponseContent, message);
+ } else {
+ assertEquals(plainResponseContent, message);
+ }
+
+ return null;
+ }
+
+ @Override public String toString() {
+ return "Client Connection";
}
}
}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
index 056b521..778e527 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
@@ -34,7 +34,6 @@
TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.io");
suite.addTestSuite(BufferedReaderTest.class);
- suite.addTestSuite(FileCanonPathCacheTest.class);
suite.addTestSuite(FilePermissionTest.class);
suite.addTestSuite(FileTest.class);
suite.addTestSuite(InputStreamReaderTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileCanonPathCacheTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileCanonPathCacheTest.java
deleted file mode 100644
index f2ac7f3..0000000
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileCanonPathCacheTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.tests.java.io;
-
-import java.io.File;
-
-import org.apache.harmony.luni.internal.io.FileCanonPathCache;
-
-import junit.framework.TestCase;
-
-public class FileCanonPathCacheTest extends TestCase {
-
- private static int DEFAULT_TIMEOUT = 600000;
-
- @Override
- public void setUp() throws Exception {
- FileCanonPathCache.clear();
- FileCanonPathCache.setTimeout(DEFAULT_TIMEOUT);
- }
-
- public void testGetSet() throws Exception {
- File file1 = new File("test/hello~1");
- assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
- FileCanonPathCache.put(file1.getAbsolutePath(), file1
- .getCanonicalPath());
- assertEquals(file1.getCanonicalPath(), FileCanonPathCache.get(file1
- .getAbsolutePath()));
-
- File file2 = new File("test/world~1");
- assertNull(FileCanonPathCache.get(file2.getAbsolutePath()));
- FileCanonPathCache.put(file2.getAbsolutePath(), file2
- .getCanonicalPath());
- assertEquals(file2.getCanonicalPath(), FileCanonPathCache.get(file2
- .getAbsolutePath()));
-
- assertNull(FileCanonPathCache.get("notexist"));
- }
-
- public void testGetTimeout01() throws Exception {
- FileCanonPathCache.setTimeout(10);
-
- File file1 = new File("test/hello~1");
- assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
- FileCanonPathCache.put(file1.getAbsolutePath(), file1
- .getCanonicalPath());
- Thread.sleep(50);
- assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
- }
-
- public void testGetTimeout02() throws Exception {
- FileCanonPathCache.setTimeout(10);
-
- File file1 = new File("test/hello~1");
- assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
- FileCanonPathCache.put(file1.getAbsolutePath(), file1
- .getCanonicalPath());
- File file2 = new File("test/hello~2");
- assertNull(FileCanonPathCache.get(file2.getAbsolutePath()));
- FileCanonPathCache.put(file2.getAbsolutePath(), file2
- .getCanonicalPath());
- File file3 = new File("test/hello~3");
- assertNull(FileCanonPathCache.get(file3.getAbsolutePath()));
- FileCanonPathCache.put(file3.getAbsolutePath(), file3
- .getCanonicalPath());
- File file4 = new File("test/hello~4");
- assertNull(FileCanonPathCache.get(file4.getAbsolutePath()));
- FileCanonPathCache.put(file4.getAbsolutePath(), file4
- .getCanonicalPath());
- File file5 = new File("test/hello~5");
- assertNull(FileCanonPathCache.get(file5.getAbsolutePath()));
- FileCanonPathCache.put(file5.getAbsolutePath(), file5
- .getCanonicalPath());
-
- Thread.sleep(50);
-
- assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
- assertNull(FileCanonPathCache.get(file2.getAbsolutePath()));
- assertNull(FileCanonPathCache.get(file3.getAbsolutePath()));
- assertNull(FileCanonPathCache.get(file4.getAbsolutePath()));
- assertNull(FileCanonPathCache.get(file5.getAbsolutePath()));
- }
-
- public void testCacheFull() throws Exception {
- int cacheSize = FileCanonPathCache.CACHE_SIZE;
- File[] files = new File[cacheSize];
- for (int i = 0; i < cacheSize; ++i) {
- files[i] = new File("test/world" + i);
- FileCanonPathCache.put(files[i].getAbsolutePath(), files[i]
- .getCanonicalPath());
- }
-
- for (int i = cacheSize; i < files.length; ++i) {
- assertEquals(files[i - cacheSize].getCanonicalPath(),
- FileCanonPathCache.get(files[i - cacheSize]
- .getAbsolutePath()));
- files[i] = new File("test/world" + i);
- FileCanonPathCache.put(files[i].getAbsolutePath(), files[i]
- .getCanonicalPath());
- assertEquals(files[i].getCanonicalPath(), FileCanonPathCache
- .get(files[i].getAbsolutePath()));
- assertNull(FileCanonPathCache.get(files[i - cacheSize]
- .getAbsolutePath()));
- }
- }
-}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
index 84cddf2..53ce506 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
@@ -25,10 +25,21 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import tests.util.TestEnvironment;
@TestTargetClass(File.class)
public class FileTest extends TestCase {
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
/**
* @tests java.io.File#File(java.io.File, java.lang.String)
*/
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java
index b1ad88a..6ffa471 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java
@@ -999,6 +999,19 @@
}
/**
+ * @tests java.lang.Float#parseFloat(java.lang.String)
+ */
+ public void test_parseFloat_LString_Harmony6261() {
+ // Regression test for HARMONY-6261
+ float f = new Float("2147483648");
+ assertEquals("2.1474836E9", Float.toString(f));
+
+ doTestCompareRawBits("123456790528.000000000000000f", 0x51e5f4c9, "1.2345679E11");
+ doTestCompareRawBits("8589934592", 0x50000000, "8.5899346E9");
+ doTestCompareRawBits("8606711808", 0x50004000, "8.606712E9");
+ }
+
+ /**
* @tests java.lang.Float#shortValue()
*/
@TestTargetNew(
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
index cb35324..283c1db 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
@@ -312,7 +312,7 @@
method = "isCompatibleWith",
args = {java.lang.String.class}
)
- @KnownFailure("isCompatibleWith returns incorrect value.")
+ @KnownFailure("Dalvik packages are always version '0.0'.")
public void test_isCompatibleWithLjava_lang_String() throws Exception {
Package p = getTestPackage("hyts_c.jar", "p.C");
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
index b1de669..1b61d6f 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
@@ -33,6 +33,7 @@
import java.util.Vector;
import tests.support.resource.Support_Resources;
+import tests.util.TestEnvironment;
@TestTargetClass(Runtime.class)
public class RuntimeTest extends junit.framework.TestCase {
@@ -72,6 +73,11 @@
return new RuntimeTest("FT");
}
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
/**
* @tests java.lang.Runtime#exec(java.lang.String)
*/
@@ -864,7 +870,6 @@
byte[] expected = {72, 0, 101, 0, 97, 0, 114, 0, 116, 0, 32, 0, 60, 47};
byte[] returned = new byte[expected.length];
- String oldEncoding = System.getProperty("file.encoding");
System.setProperty("file.encoding", "UTF-16LE");
try {
@@ -883,8 +888,6 @@
Arrays.equals(expected, returned));
} catch (UnsupportedEncodingException e) {
fail("UnsupportedEncodingException was thrown.");
- } finally {
- System.setProperty("file.encoding", oldEncoding);
}
}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java
index f17c3d8..9bad94f 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java
@@ -22,6 +22,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import tests.util.TestEnvironment;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -1080,10 +1081,9 @@
method = "load",
args = {java.lang.String.class}
)
- @AndroidOnly("No x86 version of this library")
public void test_load() {
try {
- new TestLibrary().checkString();
+ Runtime.getRuntime().load("nonExistentLibrary");
fail("UnsatisfiedLinkError was not thrown.");
} catch(UnsatisfiedLinkError e) {
//expected
@@ -1117,7 +1117,7 @@
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- System.load("libTestLibrary.so");
+ System.load("/nonExistentLibrary.so");
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
@@ -1161,7 +1161,7 @@
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- System.loadLibrary("libTestLibrary.so");
+ System.loadLibrary("nonExistentLibrary.so");
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
@@ -1207,10 +1207,16 @@
@Override
protected void setUp() {
+ TestEnvironment.reset();
flag = false;
ranFinalize = false;
}
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
protected SystemTest createInstance() {
return new SystemTest("FT");
}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TestLibrary.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TestLibrary.java
deleted file mode 100644
index 2748223..0000000
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TestLibrary.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.tests.java.lang;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-class TestLibrary {
- private native String printName();
-
- boolean checkString() {
- if(printName().equals("TestLibrary"))
- return true;
- return false;
- }
-
- TestLibrary() {
- InputStream in = TestLibrary.class.getResourceAsStream("/libTestLibrary.so");
- try {
- File tmp = File.createTempFile("libTestLibrary", "so");
- tmp.deleteOnExit();
- FileOutputStream out = new FileOutputStream(tmp);
- while (in.available() > 0) {
- out.write(in.read()); // slow
- }
- in.close();
- out.close();
- Runtime.getRuntime().load(tmp.getAbsolutePath());
- } catch (FileNotFoundException e) {
- } catch (IOException e) {
- }
- }
-}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java
index 5635ecb..4053271 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetAddressTest.java
@@ -39,6 +39,7 @@
import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
import tests.support.Support_Configuration;
+import tests.util.TestEnvironment;
@TestTargetClass(InetAddress.class)
public class InetAddressTest extends junit.framework.TestCase {
@@ -49,6 +50,16 @@
protected static String threadedTestErrorString;
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
/**
* This class is used to test inet_ntoa, gethostbyaddr and gethostbyname
* functions in the VM to make sure they're threadsafe. getByName will cause
@@ -391,60 +402,47 @@
}
// Make sure there is no caching
- String originalPropertyValue = System
- .getProperty("networkaddress.cache.ttl");
System.setProperty("networkaddress.cache.ttl", "0");
// Test for threadsafety
- try {
- InetAddress lookup1 = InetAddress
- .getByName(Support_Configuration.InetTestAddress);
- assertTrue(lookup1 + " expected "
- + Support_Configuration.InetTestIP,
- Support_Configuration.InetTestIP.equals(lookup1
- .getHostAddress()));
- InetAddress lookup2 = InetAddress
- .getByName(Support_Configuration.InetTestAddress2);
- assertTrue(lookup2 + " expected "
- + Support_Configuration.InetTestIP2,
- Support_Configuration.InetTestIP2.equals(lookup2
- .getHostAddress()));
- threadsafeTestThread thread1 = new threadsafeTestThread("1",
- lookup1.getHostName(), lookup1, 0);
- threadsafeTestThread thread2 = new threadsafeTestThread("2",
- lookup2.getHostName(), lookup2, 0);
- threadsafeTestThread thread3 = new threadsafeTestThread("3",
- lookup1.getHostAddress(), lookup1, 1);
- threadsafeTestThread thread4 = new threadsafeTestThread("4",
- lookup2.getHostAddress(), lookup2, 1);
+ InetAddress lookup1 = InetAddress
+ .getByName(Support_Configuration.InetTestAddress);
+ assertTrue(lookup1 + " expected "
+ + Support_Configuration.InetTestIP,
+ Support_Configuration.InetTestIP.equals(lookup1
+ .getHostAddress()));
+ InetAddress lookup2 = InetAddress
+ .getByName(Support_Configuration.InetTestAddress2);
+ assertTrue(lookup2 + " expected "
+ + Support_Configuration.InetTestIP2,
+ Support_Configuration.InetTestIP2.equals(lookup2
+ .getHostAddress()));
+ threadsafeTestThread thread1 = new threadsafeTestThread("1",
+ lookup1.getHostName(), lookup1, 0);
+ threadsafeTestThread thread2 = new threadsafeTestThread("2",
+ lookup2.getHostName(), lookup2, 0);
+ threadsafeTestThread thread3 = new threadsafeTestThread("3",
+ lookup1.getHostAddress(), lookup1, 1);
+ threadsafeTestThread thread4 = new threadsafeTestThread("4",
+ lookup2.getHostAddress(), lookup2, 1);
- // initialize the flags
- threadedTestSucceeded = true;
- synchronized (someoneDone) {
- thread1.start();
- thread2.start();
- thread3.start();
- thread4.start();
- }
- thread1.join();
- thread2.join();
- thread3.join();
- thread4.join();
- /* FIXME: comment the assertion below because it is platform/configuration dependent
- * Please refer to HARMONY-1664 (https://issues.apache.org/jira/browse/HARMONY-1664)
- * for details
- */
-// assertTrue(threadedTestErrorString, threadedTestSucceeded);
- } finally {
- // restore the old value of the property
- if (originalPropertyValue == null)
- // setting the property to -1 has the same effect as having the
- // property be null
- System.setProperty("networkaddress.cache.ttl", "-1");
- else
- System.setProperty("networkaddress.cache.ttl",
- originalPropertyValue);
+ // initialize the flags
+ threadedTestSucceeded = true;
+ synchronized (someoneDone) {
+ thread1.start();
+ thread2.start();
+ thread3.start();
+ thread4.start();
}
+ thread1.join();
+ thread2.join();
+ thread3.join();
+ thread4.join();
+ /* FIXME: comment the assertion below because it is platform/configuration dependent
+ * Please refer to HARMONY-1664 (https://issues.apache.org/jira/browse/HARMONY-1664)
+ * for details
+ */
+// assertTrue(threadedTestErrorString, threadedTestSucceeded);
}
/**
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java
index b4eb0ad..188d88d 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java
@@ -27,6 +27,7 @@
import tests.support.Support_Configuration;
import tests.support.Support_PortManager;
import tests.support.resource.Support_Resources;
+import tests.util.TestEnvironment;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -60,6 +61,17 @@
public class URLTest extends TestCase {
private static final String helloWorldString = "Hello World";
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
/**
* @tests java.net.URL#getHost()
*/
@@ -137,19 +149,12 @@
public void test_java_protocol_handler_pkgs_prop() throws MalformedURLException {
// Regression test for Harmony-3094
final String HANDLER_PKGS = "java.protocol.handler.pkgs";
- String pkgs = System.getProperty(HANDLER_PKGS);
System.setProperty(HANDLER_PKGS, "fake|org.apache.harmony.luni.tests.java.net");
try {
new URL("test_protocol", "", "fake.jar");
} catch (MalformedURLException e) {
// expected
- } finally {
- if (pkgs == null) {
- System.clearProperty(HANDLER_PKGS);
- } else {
- System.setProperty(HANDLER_PKGS, pkgs);
- }
}
}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java
index e5e3c11..9bd09b4 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java
@@ -212,7 +212,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
}
diff --git a/luni/src/test/java/tests/AllTests.java b/luni/src/test/java/tests/AllTests.java
index 893cdf0..c54d388 100644
--- a/luni/src/test/java/tests/AllTests.java
+++ b/luni/src/test/java/tests/AllTests.java
@@ -32,6 +32,7 @@
public static final Test suite() {
TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ // Harmony-written test suites (often with Android tests added in).
suite.addTest(tests.annotation.AllTests.suite());
suite.addTest(tests.archive.AllTests.suite());
suite.addTest(tests.concurrent.AllTests.suite());
@@ -53,8 +54,15 @@
suite.addTest(tests.text.AllTests.suite());
suite.addTest(tests.xml.AllTests.suite());
suite.addTest(tests.xnet.AllTests.suite());
-
+
+ // Android-written test suites.
+ suite.addTest(com.ibm.icu4jni.util.AllTests.suite());
+ suite.addTest(java.lang.AllTests.suite());
+ suite.addTest(java.lang.reflect.AllTests.suite());
+ suite.addTest(java.net.AllTests.suite());
+ suite.addTest(java.nio.charset.AllTests.suite());
suite.addTest(org.apache.harmony.luni.platform.AllTests.suite());
+ suite.addTest(tests.api.org.apache.harmony.kernel.dalvik.AllTests.suite());
return suite;
}
diff --git a/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java b/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java
index b1a5755..f88b3f5 100644
--- a/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java
+++ b/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java
@@ -24,12 +24,14 @@
import java.io.InputStreamReader;
import java.io.PipedReader;
import java.io.Reader;
+import java.io.StringReader;
import tests.support.Support_ASimpleReader;
import tests.support.Support_StringReader;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import tests.support.ThrowingReader;
@TestTargetClass(BufferedReader.class)
public class BufferedReaderTest extends junit.framework.TestCase {
@@ -502,6 +504,33 @@
ssr.throwExceptionOnNextUse = false;
}
+ public void testReadZeroLengthArray() throws IOException {
+ br = new BufferedReader(new Support_StringReader("ABCDEF"));
+ br.read();
+ br.read();
+ assertEquals(0, br.read(new char[6], 3, 0));
+ }
+
+ public void testSourceThrowsWithMark() throws IOException {
+ br = new BufferedReader(new ThrowingReader(
+ new StringReader("ABCDEFGHI"), 4));
+
+ br.read();
+ br.read();
+ br.mark(10);
+ br.read();
+ br.read();
+
+ try {
+ br.read();
+ fail();
+ } catch (IOException fromThrowingReader) {
+ }
+
+ assertEquals('E', br.read());
+ assertEquals('F', br.read());
+ }
+
/**
* Tears down the fixture, for example, close a network connection. This
* method is called after a test is executed.
diff --git a/luni/src/test/java/tests/api/java/io/FilePermissionTest.java b/luni/src/test/java/tests/api/java/io/FilePermissionTest.java
index 27f416d..2fa0828 100644
--- a/luni/src/test/java/tests/api/java/io/FilePermissionTest.java
+++ b/luni/src/test/java/tests/api/java/io/FilePermissionTest.java
@@ -17,28 +17,34 @@
package tests.api.java.io;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import tests.util.TestEnvironment;
+
import java.io.File;
import java.io.FilePermission;
import java.security.PermissionCollection;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
@TestTargetClass(FilePermission.class)
public class FilePermissionTest extends junit.framework.TestCase {
- FilePermission readAllFiles = new FilePermission("<<ALL FILES>>", "read");
+ FilePermission readAllFiles;
+ FilePermission alsoReadAllFiles;
+ FilePermission allInCurrent;
+ FilePermission readInCurrent;
+ FilePermission readInFile;
- FilePermission alsoReadAllFiles = new FilePermission("<<ALL FILES>>",
- "read");
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
- FilePermission allInCurrent = new FilePermission("*",
- "read, write, execute,delete");
-
- FilePermission readInCurrent = new FilePermission("*", "read");
-
- FilePermission readInFile = new FilePermission("aFile.file", "read");
+ readAllFiles = new FilePermission("<<ALL FILES>>", "read");
+ alsoReadAllFiles = new FilePermission("<<ALL FILES>>", "read");
+ allInCurrent = new FilePermission("*", "read, write, execute,delete");
+ readInCurrent = new FilePermission("*", "read");
+ readInFile = new FilePermission("aFile.file", "read");
+ }
/**
* @tests java.io.FilePermission#FilePermission(java.lang.String,
@@ -58,9 +64,9 @@
"write");
assertEquals("action given to the constructor did not correspond - constructor failed",
"write", constructFile.getActions());
- assertTrue(
- "name given to the construcotr did not correspond - construcotr failed",
- constructFile.getName() == "test constructor");
+ assertEquals(
+ "name given to the constructor did not correspond - constructor failed",
+ "test constructor", constructFile.getName());
// Regression test for HARMONY-1050
try {
@@ -244,18 +250,4 @@
readInCurrent.hashCode() != allInCurrent.hashCode());
}
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
}
diff --git a/luni/src/test/java/tests/api/java/io/FileTest.java b/luni/src/test/java/tests/api/java/io/FileTest.java
index 81f14e0..adcaccd 100644
--- a/luni/src/test/java/tests/api/java/io/FileTest.java
+++ b/luni/src/test/java/tests/api/java/io/FileTest.java
@@ -31,13 +31,15 @@
import java.net.URISyntaxException;
import java.net.URL;
-import tests.support.Support_Exec;
import dalvik.annotation.AndroidOnly;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import static tests.support.Support_Exec.javaProcessBuilder;
+import static tests.support.Support_Exec.execAndGetOutput;
+import tests.util.TestEnvironment;
@TestTargetClass(File.class)
public class FileTest extends junit.framework.TestCase {
@@ -96,7 +98,6 @@
public void test_ConstructorLjava_io_FileLjava_lang_String() throws Exception {
String error;
String dirName = System.getProperty("java.io.tmpdir");
- String oldUserDir = System.getProperty("user.dir");
System.setProperty("user.dir", dirName);
File d = new File(dirName);
@@ -126,8 +127,6 @@
d = new File(s, "/abc");
assertEquals("Test 4: Incorrect file created;",
f.getAbsolutePath(), d.getAbsolutePath());
-
- System.setProperty("user.dir", oldUserDir);
}
/**
@@ -172,7 +171,6 @@
String fileName = "input.tst";
String userDir = System.getProperty("java.io.tmpdir");
- String oldUserDir = System.getProperty("user.dir");
System.setProperty("user.dir", userDir);
File f = new File(dirName, fileName);
@@ -205,8 +203,6 @@
.getAbsolutePath());
assertEquals("Test3: Created Incorrect File", "/abc", f
.getAbsolutePath());
-
- System.setProperty("user.dir", oldUserDir);
}
/**
@@ -689,8 +685,6 @@
args = {}
)
public void test_delete() {
- // this test passes in the emulator, but it fails on the device
-
// Test for method boolean java.io.File.delete()
try {
File dir = new File(System.getProperty("java.io.tmpdir"), platformId
@@ -932,7 +926,6 @@
String expected;
String error;
String tmpDir = System.getProperty("java.io.tmpdir");
- String oldUserDir = System.getProperty("user.dir");
System.setProperty("user.dir", tmpDir);
try {
String base = new File(tmpDir).getCanonicalPath();
@@ -979,8 +972,6 @@
} catch (IOException e) {
fail("Unexpected IOException During Test : " + e.getMessage());
- } finally {
- System.setProperty("user.dir", oldUserDir);
}
}
@@ -1095,7 +1086,6 @@
args = {}
)
public void test_getPath() {
- String oldUserDir = System.getProperty("java.io.tmpdir");
System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
String base = System.getProperty("user.dir");
String fname;
@@ -1121,7 +1111,6 @@
f2.delete();
f3.delete();
f4.delete();
- System.setProperty("user.dir", oldUserDir);
}
/**
@@ -2467,12 +2456,14 @@
assertTrue("could not find the path of the test jar/apk", idx > 0);
classPath = classPath.substring(9, idx); // cutting off jar:file:
- Support_Exec.execJava(new String[] {
- "tests.support.Support_DeleteOnExitTest",
- dir.getAbsolutePath(), subDir.getAbsolutePath() },
- new String[] { System.getProperty("java.class.path"),
- classPath }, false);
- Thread.sleep(2000);
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-cp");
+ builder.command().add(System.getProperty("java.class.path"));
+ builder.command().add("tests.support.Support_DeleteOnExitTest");
+ builder.command().add(dir.getAbsolutePath());
+ builder.command().add(subDir.getAbsolutePath());
+ execAndGetOutput(builder);
+
assertFalse(dir.exists());
assertFalse(subDir.exists());
}
@@ -2502,6 +2493,9 @@
* is called before a test is executed.
*/
protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+
// Make sure that system properties are set correctly
String userDir = System.getProperty("java.io.tmpdir");
if (userDir == null)
@@ -2533,6 +2527,8 @@
* method is called after a test is executed.
*/
protected void tearDown() {
+ TestEnvironment.reset();
+
if (tempFile.exists() && !tempFile.delete())
System.out
.println("FileTest.tearDown() failed, could not delete file!");
diff --git a/luni/src/test/java/tests/api/java/io/PrintStreamTest.java b/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
index 2ec5feb..a249b38 100644
--- a/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
+++ b/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
@@ -987,7 +987,6 @@
method = "format",
args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
PrintStream tobj;
@@ -1100,7 +1099,6 @@
method = "printf",
args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
PrintStream tobj;
diff --git a/luni/src/test/java/tests/api/java/io/PrintWriterTest.java b/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
index c275525..0c17a73 100644
--- a/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
+++ b/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
@@ -1107,7 +1107,6 @@
method = "format",
args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
PrintWriter tobj;
@@ -1219,7 +1218,6 @@
method = "printf",
args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
PrintWriter tobj;
diff --git a/luni/src/test/java/tests/api/java/io/RandomAccessFileTest.java b/luni/src/test/java/tests/api/java/io/RandomAccessFileTest.java
index 3b545e3..dc35610 100644
--- a/luni/src/test/java/tests/api/java/io/RandomAccessFileTest.java
+++ b/luni/src/test/java/tests/api/java/io/RandomAccessFileTest.java
@@ -1200,16 +1200,25 @@
} catch (IOException e) {
// Expected.
}
+ // BEGIN android-added
+ try {
+ // Android uses 32-bit off_t, so anything larger than a signed 32-bit int won't work.
+ raf.seek(((long) Integer.MAX_VALUE) + 1);
+ fail("Test 2: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ // END android-added
raf.write(testString.getBytes(), 0, testLength);
raf.seek(12);
- assertEquals("Test 2: Seek failed to set file pointer.", 12,
+ assertEquals("Test 3: Seek failed to set file pointer.", 12,
raf.getFilePointer());
raf.close();
try {
raf.seek(1);
- fail("Test 1: IOException expected.");
+ fail("Test 4: IOException expected.");
} catch (IOException e) {
// Expected.
}
@@ -1296,10 +1305,21 @@
assertEquals("Test 7: Incorrect file length;",
testLength + 2, raf.length());
+ // BEGIN android-added
+ // Exception testing.
+ try {
+ // Android uses 32-bit off_t, so anything larger than a signed 32-bit int won't work.
+ raf.setLength(((long) Integer.MAX_VALUE) + 1);
+ fail("Test 8: IOException expected.");
+ } catch (IOException e) {
+ // Expected.
+ }
+ // END android-added
+
// Exception testing.
try {
raf.setLength(-1);
- fail("Test 8: IllegalArgumentException expected.");
+ fail("Test 9: IllegalArgumentException expected.");
} catch (IllegalArgumentException e) {
// Expected.
}
@@ -1307,7 +1327,7 @@
raf.close();
try {
raf.setLength(truncLength);
- fail("Test 9: IOException expected.");
+ fail("Test 10: IOException expected.");
} catch (IOException e) {
// Expected.
}
@@ -1501,4 +1521,4 @@
super.tearDown();
}
-}
\ No newline at end of file
+}
diff --git a/luni/src/test/java/tests/api/java/lang/Process2Test.java b/luni/src/test/java/tests/api/java/lang/Process2Test.java
index 51b29d8..2e60e77 100644
--- a/luni/src/test/java/tests/api/java/lang/Process2Test.java
+++ b/luni/src/test/java/tests/api/java/lang/Process2Test.java
@@ -30,6 +30,7 @@
import java.io.OutputStream;
import tests.support.Support_Exec;
+import static tests.support.Support_Exec.javaProcessBuilder;
@TestTargetClass(Process.class)
public class Process2Test extends junit.framework.TestCase {
@@ -60,23 +61,12 @@
)
})
@AndroidOnly("dalvikvm specific")
- public void test_isBufferedStreams() {
- // Regression test for HARMONY-2735.
- try {
- Object[] execArgs = Support_Exec.execJava2(new String[0], null, true);
- Process p = (Process) execArgs[0];
- InputStream in = p.getInputStream();
- assertNotNull(in);
- in = p.getErrorStream();
- assertNotNull(in);
- OutputStream out = p.getOutputStream();
- assertNotNull(out);
- in.close();
- out.close();
- p.destroy();
- } catch (Exception ex) {
- fail("Unexpected exception got: " + ex);
- }
+ public void test_streams()
+ throws IOException, InterruptedException {
+ Process p = javaProcessBuilder().start();
+ assertNotNull(p.getInputStream());
+ assertNotNull(p.getErrorStream());
+ assertNotNull(p.getOutputStream());
}
@TestTargetNew(
diff --git a/luni/src/test/java/tests/api/java/net/AllTests.java b/luni/src/test/java/tests/api/java/net/AllTests.java
index 5bcb484..10dd9d8 100644
--- a/luni/src/test/java/tests/api/java/net/AllTests.java
+++ b/luni/src/test/java/tests/api/java/net/AllTests.java
@@ -68,6 +68,7 @@
suite.addTestSuite(SocketPermissionTest.class);
suite.addTestSuite(SocketTest.class);
suite.addTestSuite(SocketTimeoutExceptionTest.class);
+ suite.addTestSuite(UnixSocketTest.class);
suite.addTestSuite(URISyntaxExceptionTest.class);
suite.addTestSuite(URITest.class);
suite.addTestSuite(URLClassLoaderTest.class);
diff --git a/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java b/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
index 3f35b29..853f6a6 100644
--- a/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
+++ b/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
@@ -1584,7 +1584,7 @@
try {
new java.net.DatagramSocket(isa);
- fail("SocketException was thrown.");
+ fail("SocketException was not thrown.");
} catch(SocketException se) {
//expected
}
diff --git a/luni/src/test/java/tests/api/java/net/ExcludedProxyTest.java b/luni/src/test/java/tests/api/java/net/ExcludedProxyTest.java
index ae76723..eeb46db 100644
--- a/luni/src/test/java/tests/api/java/net/ExcludedProxyTest.java
+++ b/luni/src/test/java/tests/api/java/net/ExcludedProxyTest.java
@@ -36,6 +36,7 @@
import tests.support.Support_Configuration;
import tests.support.resource.Support_Resources;
import junit.framework.TestCase;
+import tests.util.TestEnvironment;
/*
* This test is designed for collecting all the testcases which needs a proxy
@@ -46,6 +47,12 @@
@TestTargetClass(Proxy.class)
public class ExcludedProxyTest extends TestCase {
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
/**
* @tests java.net.HttpURLConnection#usingProxy()
*/
diff --git a/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
index 1429063..018d58a 100644
--- a/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
+++ b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
@@ -17,11 +17,6 @@
package tests.api.java.net;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
import java.io.IOException;
import java.net.BindException;
import java.net.DatagramPacket;
@@ -34,290 +29,205 @@
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
-import java.security.Permission;
+import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
import tests.support.Support_NetworkInterface;
import tests.support.Support_PortManager;
-@TestTargetClass(MulticastSocket.class)
public class MulticastSocketTest extends SocketTestCase {
- Thread t;
+ Thread t;
- MulticastSocket mss;
+ MulticastSocket mss;
- MulticastServer server;
+ MulticastServer server;
- // private member variables used for tests
- boolean atLeastOneInterface = false;
+ // private member variables used for tests
+ boolean atLeastOneInterface = false;
- boolean atLeastTwoInterfaces = false;
+ boolean atLeastTwoInterfaces = false;
- private NetworkInterface networkInterface1 = null;
+ private NetworkInterface networkInterface1 = null;
- private NetworkInterface networkInterface2 = null;
+ private NetworkInterface networkInterface2 = null;
- private NetworkInterface IPV6networkInterface1 = null;
+ private NetworkInterface IPV6networkInterface1 = null;
- static class MulticastServer extends Thread {
+ static class MulticastServer extends Thread {
- public MulticastSocket ms;
+ public MulticastSocket ms;
- volatile boolean running = true;
+ boolean running = true;
- private final BlockingQueue<DatagramPacket> queue
- = new ArrayBlockingQueue<DatagramPacket>(1);
+ volatile public byte[] rbuf = new byte[512];
+
+ volatile DatagramPacket rdp = null;
+
+ private InetAddress groupAddr = null;
+ private SocketAddress groupSockAddr = null;
+ private NetworkInterface groupNI = null;
public void run() {
- try {
+ try {
+ byte[] tmpbuf = new byte[512];
+ DatagramPacket tmpPack =
+ new DatagramPacket(tmpbuf, tmpbuf.length);
+
while (running) {
- try {
- byte[] rbuf = new byte[512];
- rbuf[0] = -1;
- DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
- ms.receive(rdp);
- queue.put(rdp);
+ try {
+ ms.receive(tmpPack);
+
+ System.arraycopy(tmpPack.getData(), 0, rdp.getData(),
+ rdp.getOffset(), tmpPack.getLength());
+ rdp.setLength(tmpPack.getLength());
+ rdp.setAddress(tmpPack.getAddress());
+ rdp.setPort(tmpPack.getPort());
} catch (java.io.InterruptedIOException e) {
- } catch (InterruptedException e) {
- }
- }
- } catch (java.io.IOException e) {
- System.out.println("Multicast server failed: " + e);
- } finally {
- ms.close();
- }
- }
+ Thread.yield();
+ }
+ }
+ } catch (java.io.IOException e) {
+ System.out.println("Multicast server failed: " + e);
+ } finally {
+ ms.close();
+ }
+ }
- public synchronized void leaveGroup(InetAddress aGroup)
- throws java.io.IOException {
- ms.leaveGroup(aGroup);
+ public void stopServer() {
+ running = false;
+ try {
+ if (groupAddr != null) {
+ ms.leaveGroup(groupAddr);
+ } else if (groupSockAddr != null) {
+ ms.leaveGroup(groupSockAddr, groupNI);
+ }
+ } catch (IOException e) {}
}
public MulticastServer(InetAddress anAddress, int aPort)
throws java.io.IOException {
+ rbuf = new byte[512];
+ rbuf[0] = -1;
+ rdp = new DatagramPacket(rbuf, rbuf.length);
ms = new MulticastSocket(aPort);
ms.setSoTimeout(2000);
- ms.joinGroup(anAddress);
+ groupAddr = anAddress;
+ ms.joinGroup(groupAddr);
}
-
+
+
public MulticastServer(SocketAddress anAddress, int aPort,
- NetworkInterface netInterface) throws java.io.IOException {
- ms = new MulticastSocket(aPort);
- ms.setSoTimeout(2000);
- ms.joinGroup(anAddress, netInterface);
- }
+ NetworkInterface netInterface) throws java.io.IOException {
+ rbuf = new byte[512];
+ rbuf[0] = -1;
+ rdp = new DatagramPacket(rbuf, rbuf.length);
+ ms = new MulticastSocket(aPort);
+ ms.setSoTimeout(2000);
+ groupSockAddr = anAddress;
+ groupNI = netInterface;
+ ms.joinGroup(groupSockAddr, groupNI);
+ }
+ }
- public DatagramPacket receive() throws InterruptedException {
- return queue.poll(1000, TimeUnit.MILLISECONDS);
- }
-
- public void stopServer() throws InterruptedException {
- running = false;
- interrupt();
- join();
- }
- }
-
- /**
- * @tests java.net.MulticastSocket#MulticastSocket()
- */
- @TestTargetNew(
- level = TestLevel.SUFFICIENT,
- notes = "IOException exception checking missed.",
- method = "MulticastSocket",
- args = {}
- )
- public void test_Constructor() throws IOException {
- // regression test for 497
+ /**
+ * @tests java.net.MulticastSocket#MulticastSocket()
+ */
+ public void test_Constructor() throws IOException {
+ // regression test for 497
MulticastSocket s = new MulticastSocket();
// regression test for Harmony-1162
assertTrue(s.getReuseAddress());
-
- SecurityManager sm = new SecurityManager() {
+ }
- public void checkPermission(Permission perm) {
- }
-
- public void checkListen(int port) {
- throw new SecurityException();
- }
- };
-
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- new MulticastSocket();
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (IOException e) {
- fail("IOException was thrown.");
- e.printStackTrace();
- } finally {
- System.setSecurityManager(oldSm);
- }
- }
-
- /**
- * @tests java.net.MulticastSocket#MulticastSocket(int)
- */
- @TestTargetNew(
- level = TestLevel.SUFFICIENT,
- notes = "IOException exception checking missed.",
- method = "MulticastSocket",
- args = {int.class}
- )
- public void test_ConstructorI() {
- // Test for method java.net.MulticastSocket(int)
- // Used in tests
- MulticastSocket dup = null;
- try {
- mss = new MulticastSocket();
- int port = mss.getLocalPort();
- dup = new MulticastSocket(port);
+ /**
+ * @tests java.net.MulticastSocket#MulticastSocket(int)
+ */
+ public void test_ConstructorI() throws IOException {
+ MulticastSocket orig = new MulticastSocket();
+ int port = orig.getLocalPort();
+ orig.close();
+ MulticastSocket dup = null;
+ try {
+ dup = new MulticastSocket(port);
// regression test for Harmony-1162
assertTrue(dup.getReuseAddress());
- } catch (IOException e) {
- fail("duplicate binding not allowed: " + e);
- }
-
-
-
- if (dup != null)
- dup.close();
-
- SecurityManager sm = new SecurityManager() {
+ } catch (IOException e) {
+ fail("duplicate binding not allowed: " + e);
+ }
+ if (dup != null)
+ dup.close();
+ }
- public void checkPermission(Permission perm) {
- }
-
- public void checkListen(int port) {
- throw new SecurityException();
- }
- };
+ /**
+ * @tests java.net.MulticastSocket#getInterface()
+ */
+ public void test_getInterface() throws Exception {
+ // Test for method java.net.InetAddress
+ // java.net.MulticastSocket.getInterface()
+ assertTrue("Used for testing.", true);
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- new MulticastSocket(1);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (IOException e) {
- fail("IOException was thrown.");
- e.printStackTrace();
- } finally {
- System.setSecurityManager(oldSm);
- }
- }
+ int groupPort = Support_PortManager.getNextPortForUDP();
- /**
- * @tests java.net.MulticastSocket#getInterface()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getInterface",
- args = {}
- )
- @KnownFailure("No interfaces if there's no debugger connected")
- public void test_getInterface() {
- // Test for method java.net.InetAddress
- // java.net.MulticastSocket.getInterface()
- assertTrue("Used for testing.", true);
+ if (atLeastOneInterface) {
+ // validate that we get the expected response when one was not
+ // set
+ mss = new MulticastSocket(groupPort);
+ String preferIPv4StackValue = System
+ .getProperty("java.net.preferIPv4Stack");
+ String preferIPv6AddressesValue = System
+ .getProperty("java.net.preferIPv6Addresses");
+ if (((preferIPv4StackValue == null) || preferIPv4StackValue
+ .equalsIgnoreCase("false"))
+ && (preferIPv6AddressesValue != null)
+ && (preferIPv6AddressesValue.equals("true"))) {
+ // we expect an IPv6 ANY in this case
+ assertEquals("inet Address returned when not set",
+ InetAddress.getByName("::0"),
+ mss.getInterface());
+ } else {
+ // we expect an IPv4 ANY in this case
+ assertEquals("inet Address returned when not set",
+ InetAddress.getByName("0.0.0.0"),
+ mss.getInterface());
+ }
- int groupPort = Support_PortManager.getNextPortForUDP();
- try {
- if (atLeastOneInterface) {
- // validate that we get the expected response when one was not
- // set
- mss = new MulticastSocket(groupPort);
- String preferIPv4StackValue = System
- .getProperty("java.net.preferIPv4Stack");
- String preferIPv6AddressesValue = System
- .getProperty("java.net.preferIPv6Addresses");
- if (((preferIPv4StackValue == null) || preferIPv4StackValue
- .equalsIgnoreCase("false"))
- && (preferIPv6AddressesValue != null)
- && (preferIPv6AddressesValue.equals("true"))) {
- // we expect an IPv6 ANY in this case
- assertTrue("inet Address returned when not set:"
- + mss.getInterface().toString(), InetAddress
- .getByName("::0").equals(mss.getInterface()));
- } else {
- // we expect an IPv4 ANY in this case
- assertNotNull("inet Address returned when not set:",
- mss.getInterface());
+ // validate that we get the expected response when we set via
+ // setInterface
+ Enumeration addresses = networkInterface1.getInetAddresses();
+ if (addresses.hasMoreElements()) {
+ InetAddress firstAddress = (InetAddress) addresses
+ .nextElement();
+ mss.setInterface(firstAddress);
+ assertEquals("getNetworkInterface did not return interface set by setInterface",
+ firstAddress, mss.getInterface());
+
+ groupPort = Support_PortManager.getNextPortForUDP();
+ mss = new MulticastSocket(groupPort);
+ mss.setNetworkInterface(networkInterface1);
+ assertEquals("getInterface did not return interface set by setNetworkInterface",
+ networkInterface1,
+ NetworkInterface.getByInetAddress(mss.getInterface()));
+ }
+
}
+ }
- // validate that we get the expected response when we set via
- // setInterface
- Enumeration addresses = networkInterface1.getInetAddresses();
- if (addresses != null) {
- InetAddress firstAddress = (InetAddress) addresses
- .nextElement();
- mss.setInterface(firstAddress);
- assertTrue(
- "getNetworkInterface did not return interface set " +
- "by setInterface. Expected:"
- + firstAddress + " Got:"
- + mss.getInterface(), firstAddress
- .equals(mss.getInterface()));
-
- groupPort = Support_PortManager.getNextPortForUDP();
- mss = new MulticastSocket(groupPort);
- mss.setNetworkInterface(networkInterface1);
- InetAddress addr = mss.getInterface();
- NetworkInterface if1 = NetworkInterface.getByInetAddress(addr);
- assertEquals(
- "getInterface did not return interface set by " +
- "setNeworkInterface Expected: " + firstAddress
- + "Got:" + mss.getInterface(),
- networkInterface1, if1);
- }
- mss.close();
- try {
- mss.getInterface();
- fail("SocketException was not thrown.");
- } catch(SocketException ioe) {
- //expected
- }
- }
- } catch (Exception e) {
- fail("Exception during getInterface test: " + e.toString());
- }
- }
-
- /**
- * @throws IOException
- * @tests java.net.MulticastSocket#getNetworkInterface()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getNetworkInterface",
- args = {}
- )
- @KnownFailure("No interfaces if there's no debugger connected")
- public void test_getNetworkInterface() throws IOException {
+ /**
+ * @throws IOException
+ * @tests java.net.MulticastSocket#getNetworkInterface()
+ */
+ public void test_getNetworkInterface() throws IOException {
int groupPort = Support_PortManager.getNextPortForUDP();
if (atLeastOneInterface) {
// validate that we get the expected response when one was not
// set
mss = new MulticastSocket(groupPort);
NetworkInterface theInterface = mss.getNetworkInterface();
- assertNotNull(
- "network interface returned wrong network interface when " +
- "not set:"
- + theInterface, theInterface.getInetAddresses());
+ assertTrue(
+ "network interface returned wrong network interface when not set:"
+ + theInterface, theInterface.getInetAddresses()
+ .hasMoreElements());
InetAddress firstAddress = (InetAddress) theInterface
.getInetAddresses().nextElement();
// validate we the first address in the network interface is the
@@ -330,42 +240,34 @@
.equalsIgnoreCase("false"))
&& (preferIPv6AddressesValue != null)
&& (preferIPv6AddressesValue.equals("true"))) {
- assertTrue(
- "network interface returned wrong network interface " +
- "when not set:"
- + theInterface, InetAddress.getByName("::0")
- .equals(firstAddress));
+ assertEquals("network interface returned wrong network interface when not set:"
+ + theInterface,
+ firstAddress, InetAddress.getByName("::0"));
} else {
- assertTrue(
- "network interface returned wrong network interface " +
- "when not set:"
- + theInterface, InetAddress
- .getByName("0.0.0.0").equals(firstAddress));
+ assertEquals("network interface returned wrong network interface when not set:"
+ + theInterface,
+ InetAddress.getByName("0.0.0.0"),
+ firstAddress);
}
mss.setNetworkInterface(networkInterface1);
- assertTrue(
- "getNetworkInterface did not return interface set by " +
- "setNeworkInterface",
- networkInterface1.equals(mss.getNetworkInterface()));
+ assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+ networkInterface1, mss.getNetworkInterface());
if (atLeastTwoInterfaces) {
mss.setNetworkInterface(networkInterface2);
- assertTrue(
- "getNetworkInterface did not return network interface " +
- "set by second setNetworkInterface call",
- networkInterface2.equals(mss.getNetworkInterface()));
+ assertEquals("getNetworkInterface did not return network interface set by second setNetworkInterface call",
+ networkInterface2, mss.getNetworkInterface());
}
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
if (IPV6networkInterface1 != null) {
mss.setNetworkInterface(IPV6networkInterface1);
- assertTrue(
- "getNetworkInterface did not return interface set " +
- "by setNeworkInterface",
- IPV6networkInterface1.equals(mss.getNetworkInterface()));
+ assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
+ IPV6networkInterface1,
+ mss.getNetworkInterface());
}
// validate that we get the expected response when we set via
@@ -373,191 +275,100 @@
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
Enumeration addresses = networkInterface1.getInetAddresses();
- if (addresses != null) {
+ if (addresses.hasMoreElements()) {
firstAddress = (InetAddress) addresses.nextElement();
mss.setInterface(firstAddress);
- assertTrue(
- "getNetworkInterface did not return interface set " +
- "by setInterface",
- networkInterface1.equals(mss.getNetworkInterface()));
- }
-
- mss.close();
- try {
- mss.getNetworkInterface();
- fail("SocketException was not thrown.");
- } catch(SocketException ioe) {
- //expected
+ assertEquals("getNetworkInterface did not return interface set by setInterface",
+ networkInterface1,
+ mss.getNetworkInterface());
}
}
}
- /**
- * @tests java.net.MulticastSocket#getTimeToLive()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getTimeToLive",
- args = {}
- )
- public void test_getTimeToLive() {
- try {
- mss = new MulticastSocket();
- mss.setTimeToLive(120);
- assertTrue("Returned incorrect 1st TTL: " + mss.getTimeToLive(),
- mss.getTimeToLive() == 120);
- mss.setTimeToLive(220);
- assertTrue("Returned incorrect 2nd TTL: " + mss.getTimeToLive(),
- mss.getTimeToLive() == 220);
- mss.close();
- try {
- mss.getTimeToLive();
- fail("IOException was not thrown.");
- } catch(IOException ioe) {
- //expected
- }
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
- } catch (Exception e) {
- handleException(e, SO_MULTICAST);
- }
- }
+ /**
+ * @tests java.net.MulticastSocket#getTimeToLive()
+ */
+ public void test_getTimeToLive() {
+ try {
+ mss = new MulticastSocket();
+ mss.setTimeToLive(120);
+ assertEquals("Returned incorrect 1st TTL",
+ 120, mss.getTimeToLive());
+ mss.setTimeToLive(220);
+ assertEquals("Returned incorrect 2nd TTL",
+ 220, mss.getTimeToLive());
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+ } catch (Exception e) {
+ handleException(e, SO_MULTICAST);
+ }
+ }
- /**
- * @tests java.net.MulticastSocket#getTTL()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getTTL",
- args = {}
- )
- public void test_getTTL() {
- // Test for method byte java.net.MulticastSocket.getTTL()
+ /**
+ * @tests java.net.MulticastSocket#getTTL()
+ */
+ public void test_getTTL() {
+ // Test for method byte java.net.MulticastSocket.getTTL()
- try {
- mss = new MulticastSocket();
- mss.setTTL((byte) 120);
- assertTrue("Returned incorrect TTL: " + mss.getTTL(),
- mss.getTTL() == 120);
- mss.close();
- try {
- mss.getTTL();
- fail("IOException was not thrown.");
- } catch(IOException ioe) {
- //expected
- }
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
- } catch (Exception e) {
- handleException(e, SO_MULTICAST);
- }
- }
+ try {
+ mss = new MulticastSocket();
+ mss.setTTL((byte) 120);
+ assertEquals("Returned incorrect TTL",
+ 120, mss.getTTL());
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+ } catch (Exception e) {
+ handleException(e, SO_MULTICAST);
+ }
+ }
- /**
- * @tests java.net.MulticastSocket#joinGroup(java.net.InetAddress)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "joinGroup",
- args = {java.net.InetAddress.class}
- )
- public void test_joinGroupLjava_net_InetAddress() throws InterruptedException {
- // Test for method void
- // java.net.MulticastSocket.joinGroup(java.net.InetAddress)
- String msg = null;
- InetAddress group = null;
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
- int groupPort = ports[0];
- try {
- group = InetAddress.getByName("224.0.0.3");
- server = new MulticastServer(group, groupPort);
- server.start();
- Thread.sleep(1000);
- msg = "Hello World";
- mss = new MulticastSocket(ports[1]);
- DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
- .length(), group, groupPort);
- mss.joinGroup(group);
- mss.send(sdp, (byte) 10);
+ /**
+ * @tests java.net.MulticastSocket#joinGroup(java.net.InetAddress)
+ */
+ public void test_joinGroupLjava_net_InetAddress() throws Exception {
+ // Test for method void
+ // java.net.MulticastSocket.joinGroup(java.net.InetAddress)
+ String msg = null;
+ InetAddress group = null;
+ int[] ports = Support_PortManager.getNextPortsForUDP(2);
+ int groupPort = ports[0];
+ group = InetAddress.getByName("224.0.0.3");
+ server = new MulticastServer(group, groupPort);
+ server.start();
+ Thread.sleep(1000);
+ msg = "Hello World";
+ mss = new MulticastSocket(ports[1]);
+ DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
+ .length(), group, groupPort);
+ mss.send(sdp, (byte) 10);
+ Thread.sleep(1000);
- SecurityManager sm = new SecurityManager() {
+ assertEquals("Group member did not recv data",
+ msg,
+ new String(server.rdp.getData(), 0, server.rdp.getLength()));
+ }
- public void checkPermission(Permission perm) {
- }
-
- public void checkMulticast(InetAddress maddr) {
- throw new SecurityException();
- }
- };
+ /**
+ * @throws IOException
+ * @throws InterruptedException
+ * @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,java.net.NetworkInterface)
+ */
+ public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws IOException, InterruptedException {
+ // security manager that allows us to check that we only return the
+ // addresses that we should
+ class mySecurityManager extends SecurityManager {
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- mss.joinGroup(group);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (IOException e) {
- fail("IOException was thrown.");
- e.printStackTrace();
- } finally {
- System.setSecurityManager(oldSm);
- }
-
- mss.close();
- try {
- mss.joinGroup(group);
- fail("SocketException was not thrown.");
- } catch(SocketException ioe) {
- //expected
- }
- } catch (Exception e) {
- fail("Exception during joinGroup test: " + e.toString());
- }
- DatagramPacket rdb = server.receive();
+ public void checkMulticast(InetAddress address) {
+ throw new SecurityException("not allowed");
+ }
+ }
- assertEquals("Group member did not recv data: ", msg,
- new String(rdb.getData(), 0, rdb.getLength()));
+ String msg = null;
+ InetAddress group = null;
+ SocketAddress groupSockAddr = null;
+ int[] ports = Support_PortManager.getNextPortsForUDP(2);
+ int groupPort = ports[0];
+ int serverPort = ports[1];
- }
-
- /**
- * @throws IOException
- * @throws InterruptedException
- * @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,
- * java.net.NetworkInterface)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "joinGroup",
- args = {java.net.SocketAddress.class, java.net.NetworkInterface.class}
- )
- public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface()
- throws IOException, InterruptedException {
- // security manager that allows us to check that we only return the
- // addresses that we should
- class mySecurityManager extends SecurityManager {
-
- public void checkPermission(Permission perm) {
- }
-
- public void checkMulticast(InetAddress address) {
- throw new SecurityException("not allowed");
- }
- }
-
- String msg = null;
- InetAddress group = null;
- SocketAddress groupSockAddr = null;
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
- int groupPort = ports[0];
- int serverPort = ports[1];
-
- Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
+ Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
// first validate that we handle a null group ok
mss = new MulticastSocket(groupPort);
@@ -613,11 +424,11 @@
.length(), group, serverPort);
mss.setTimeToLive(2);
mss.send(sdp);
- DatagramPacket rdp = server.receive();
-
+ Thread.sleep(1000);
// now vaildate that we received the data as expected
- assertEquals("Group member did not recv data: ", msg,
- new String(rdp.getData(), 0, rdp.getLength()));
+ assertEquals("Group member did not recv data",
+ msg,
+ new String(server.rdp.getData(), 0, server.rdp.getLength()));
server.stopServer();
// now validate that we handled the case were we join a
@@ -638,9 +449,11 @@
sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2,
serverPort);
mss.send(sdp);
- rdp = server.receive();
- assertNull("Group member received data when sent on different group",
- rdp);
+ Thread.sleep(1000);
+ assertFalse(
+ "Group member received data when sent on different group: ",
+ new String(server.rdp.getData(), 0, server.rdp.getLength())
+ .equals(msg));
server.stopServer();
// if there is more than one network interface then check that
@@ -651,39 +464,47 @@
NetworkInterface loopbackInterface = NetworkInterface
.getByInetAddress(InetAddress.getByName("127.0.0.1"));
+ boolean anyLoop = networkInterface1.equals(loopbackInterface) || networkInterface2.equals(loopbackInterface);
+
+ ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
theInterfaces = NetworkInterface.getNetworkInterfaces();
while (theInterfaces.hasMoreElements()) {
-
- NetworkInterface thisInterface = (NetworkInterface)
- theInterfaces.nextElement();
- if ((thisInterface.getInetAddresses() != null && thisInterface
- .getInetAddresses().hasMoreElements())
+ NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
+ if (thisInterface.getInetAddresses().hasMoreElements()
&& (Support_NetworkInterface
- .useInterface(thisInterface) == true)) {
+ .useInterface(thisInterface) == true)){
+ realInterfaces.add(thisInterface);
+ }
+ }
+
+ for (int i = 0; i < realInterfaces.size(); i++) {
+ final int SECOND = 1;
+ NetworkInterface thisInterface = realInterfaces.get(i);
+
// get the first address on the interface
// start server which is joined to the group and has
// only asked for packets on this interface
- Enumeration addresses = thisInterface
- .getInetAddresses();
+ Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
NetworkInterface sendingInterface = null;
- boolean isLoopback = false;
- if (addresses != null) {
- InetAddress firstAddress = (InetAddress) addresses
- .nextElement();
- if (firstAddress.isLoopbackAddress()) {
- isLoopback = true;
- }
+ if (addresses.hasMoreElements()) {
+ InetAddress firstAddress = (InetAddress) addresses.nextElement();
if (firstAddress instanceof Inet4Address) {
group = InetAddress.getByName("224.0.0.4");
- if (networkInterface1.equals(NetworkInterface
- .getByInetAddress(InetAddress
- .getByName("127.0.0.1")))) {
- sendingInterface = networkInterface2;
+ if (anyLoop) {
+ if (networkInterface1.equals(loopbackInterface)) {
+ sendingInterface = networkInterface2;
+ } else {
+ sendingInterface = networkInterface1;
+ }
} else {
- sendingInterface = networkInterface1;
+ if(i == SECOND){
+ sendingInterface = networkInterface2;
+ } else {
+ sendingInterface = networkInterface1;
}
+ }
} else {
// if this interface only seems to support
// IPV6 addresses
@@ -693,13 +514,6 @@
}
}
- InetAddress useAddress = null;
- addresses = sendingInterface.getInetAddresses();
- if ((addresses != null)
- && (addresses.hasMoreElements())) {
- useAddress = (InetAddress) addresses.nextElement();
- }
-
ports = Support_PortManager.getNextPortsForUDP(2);
serverPort = ports[0];
groupPort = ports[1];
@@ -712,33 +526,27 @@
// Now send out a package on interface
// networkInterface 1. We should
// only see the packet if we send it on interface 1
- InetSocketAddress theAddress = new InetSocketAddress(
- useAddress, groupPort);
mss = new MulticastSocket(groupPort);
mss.setNetworkInterface(sendingInterface);
msg = "Hello World - Again" + thisInterface.getName();
sdp = new DatagramPacket(msg.getBytes(), msg.length(),
group, serverPort);
mss.send(sdp);
- rdp = server.receive();
-
+ Thread.sleep(1000);
if (thisInterface.equals(sendingInterface)) {
- assertEquals(
- "Group member did not recv data when " +
- "bound on specific interface: ", msg,
- new String(rdp.getData(), 0, rdp.getLength()));
+ assertEquals("Group member did not recv data when bound on specific interface",
+ msg,
+ new String(server.rdp.getData(), 0, server.rdp.getLength()));
} else {
assertFalse(
- "Group member received data on other " +
- "interface when only asked for it on one " +
- "interface: ",
- new String(rdp.getData(), 0,
- rdp.getLength()).equals(msg));
+ "Group member received data on other interface when only asked for it on one interface: ",
+ new String(server.rdp.getData(), 0,
+ server.rdp.getLength()).equals(msg));
}
server.stopServer();
}
- }
+
// validate that we can join the same address on two
// different interfaces but not on the same interface
@@ -748,373 +556,252 @@
mss.joinGroup(groupSockAddr, networkInterface2);
try {
mss.joinGroup(groupSockAddr, networkInterface1);
- fail("Did not get expected exception when joining for " +
- "second time on same interface");
+ fail("Did not get expected exception when joining for second time on same interface");
} catch (IOException e) {
}
}
}
- System.setSecurityManager(null);
- }
+ System.setSecurityManager(null);
+ }
- /**
- * @tests java.net.MulticastSocket#leaveGroup(java.net.InetAddress)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "leaveGroup",
- args = {java.net.InetAddress.class}
- )
- public void test_leaveGroupLjava_net_InetAddress() {
- // Test for method void
- // java.net.MulticastSocket.leaveGroup(java.net.InetAddress)
- String msg = null;
- boolean except = false;
- InetAddress group = null;
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
- int groupPort = ports[0];
+ /**
+ * @tests java.net.MulticastSocket#leaveGroup(java.net.InetAddress)
+ */
+ public void test_leaveGroupLjava_net_InetAddress() {
+ // Test for method void
+ // java.net.MulticastSocket.leaveGroup(java.net.InetAddress)
+ String msg = null;
+ boolean except = false;
+ InetAddress group = null;
+ int[] ports = Support_PortManager.getNextPortsForUDP(2);
+ int groupPort = ports[0];
- try {
- group = InetAddress.getByName("224.0.0.3");
- msg = "Hello World";
- mss = new MulticastSocket(ports[1]);
- DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
- .length(), group, groupPort);
- mss.send(sdp, (byte) 10);
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
- } catch (Exception e) {
- handleException(e, SO_MULTICAST);
- }
- try {
- // Try to leave s group that mss is not a member of
- mss.leaveGroup(group);
- } catch (java.io.IOException e) {
- // Correct
- except = true;
- }
- assertTrue("Failed to throw exception leaving non-member group", except);
-
- SecurityManager sm = new SecurityManager() {
+ try {
+ group = InetAddress.getByName("224.0.0.3");
+ msg = "Hello World";
+ mss = new MulticastSocket(ports[1]);
+ DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
+ .length(), group, groupPort);
+ mss.send(sdp, (byte) 10);
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+ } catch (Exception e) {
+ handleException(e, SO_MULTICAST);
+ }
+ try {
+ // Try to leave s group that mss is not a member of
+ mss.leaveGroup(group);
+ } catch (java.io.IOException e) {
+ // Correct
+ except = true;
+ }
+ assertTrue("Failed to throw exception leaving non-member group", except);
+ }
- public void checkPermission(Permission perm) {
- }
-
- public void checkMulticast(InetAddress maddr) {
- throw new SecurityException();
- }
- };
+ /**
+ * @tests java.net.MulticastSocket#leaveGroup(java.net.SocketAddress,java.net.NetworkInterface)
+ */
+ public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
+ // security manager that allows us to check that we only return the
+ // addresses that we should
+ class mySecurityManager extends SecurityManager {
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- mss.leaveGroup(group);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (IOException e) {
- fail("IOException was thrown.");
- e.printStackTrace();
- } finally {
- System.setSecurityManager(oldSm);
- }
- }
+ public void checkMulticast(InetAddress address) {
+ throw new SecurityException("not allowed");
+ }
+ }
- /**
- * @tests java.net.MulticastSocket#leaveGroup(java.net.SocketAddress,
- * java.net.NetworkInterface)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "leaveGroup",
- args = {java.net.SocketAddress.class, java.net.NetworkInterface.class}
- )
- public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface() {
- // security manager that allows us to check that we only return the
- // addresses that we should
- class mySecurityManager extends SecurityManager {
-
- public void checkPermission(Permission p) {
- }
+ String msg = null;
+ InetAddress group = null;
+ int groupPort = Support_PortManager.getNextPortForUDP();
+ SocketAddress groupSockAddr = null;
+ SocketAddress groupSockAddr2 = null;
- public void checkMulticast(InetAddress address) {
- throw new SecurityException("not allowed");
- }
- }
+ Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
- String msg = null;
- InetAddress group = null;
- int groupPort = Support_PortManager.getNextPortForUDP();
- SocketAddress groupSockAddr = null;
- SocketAddress groupSockAddr2 = null;
-
- try {
- Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
-
- // first validate that we handle a null group ok
- mss = new MulticastSocket(groupPort);
- try {
- mss.leaveGroup(null, null);
- fail("Did not get exception when group was null");
- } catch (IllegalArgumentException e) {
- }
-
- // now validate we get the expected error if the address specified
- // is not a multicast group
- try {
- group = InetAddress.getByName("255.255.255.255");
- groupSockAddr = new InetSocketAddress(group, groupPort);
- mss.leaveGroup(groupSockAddr, null);
- fail("Did not get exception when group is not a " +
- "multicast address");
- } catch (IOException e) {
- }
-
- // now try to leave a group if we are not authorized
- // set the security manager that will make the first address not
- // visible
- System.setSecurityManager(new mySecurityManager());
- try {
- group = InetAddress.getByName("224.0.0.3");
- groupSockAddr = new InetSocketAddress(group, groupPort);
- mss.leaveGroup(groupSockAddr, null);
- fail("Did not get exception when joining group is " +
- "not allowed");
- } catch (SecurityException e) {
- }
- System.setSecurityManager(null);
-
- if (atLeastOneInterface) {
-
- // now test that we can join and leave a group successfully
- groupPort = Support_PortManager.getNextPortForUDP();
+ // first validate that we handle a null group ok
mss = new MulticastSocket(groupPort);
- groupSockAddr = new InetSocketAddress(group, groupPort);
- mss.joinGroup(groupSockAddr, null);
- mss.leaveGroup(groupSockAddr, null);
try {
- mss.leaveGroup(groupSockAddr, null);
- fail(
- "Did not get exception when trying to leave " +
- "group that was allready left");
+ mss.leaveGroup(null, null);
+ fail("Did not get exception when group was null");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // now validate we get the expected error if the address specified
+ // is not a multicast group
+ try {
+ group = InetAddress.getByName("255.255.255.255");
+ groupSockAddr = new InetSocketAddress(group, groupPort);
+ mss.leaveGroup(groupSockAddr, null);
+ fail("Did not get exception when group is not a multicast address");
} catch (IOException e) {
}
- InetAddress group2 = InetAddress.getByName("224.0.0.4");
- groupSockAddr2 = new InetSocketAddress(group2, groupPort);
- mss.joinGroup(groupSockAddr, networkInterface1);
+ // now try to leave a group if we are not authorized
+ // set the security manager that will make the first address not
+ // visible
+ System.setSecurityManager(new mySecurityManager());
try {
- mss.leaveGroup(groupSockAddr2, networkInterface1);
- fail(
- "Did not get exception when trying to leave " +
- "group that was never joined");
- } catch (IOException e) {
+ group = InetAddress.getByName("224.0.0.3");
+ groupSockAddr = new InetSocketAddress(group, groupPort);
+ mss.leaveGroup(groupSockAddr, null);
+ fail("Did not get exception when joining group is not allowed");
+ } catch (SecurityException e) {
+ }
+ System.setSecurityManager(null);
+
+ if (atLeastOneInterface) {
+
+ // now test that we can join and leave a group successfully
+ groupPort = Support_PortManager.getNextPortForUDP();
+ mss = new MulticastSocket(groupPort);
+ groupSockAddr = new InetSocketAddress(group, groupPort);
+ mss.joinGroup(groupSockAddr, null);
+ mss.leaveGroup(groupSockAddr, null);
+ try {
+ mss.leaveGroup(groupSockAddr, null);
+ fail(
+ "Did not get exception when trying to leave group that was allready left");
+ } catch (IOException e) {
+ }
+
+ InetAddress group2 = InetAddress.getByName("224.0.0.4");
+ groupSockAddr2 = new InetSocketAddress(group2, groupPort);
+ mss.joinGroup(groupSockAddr, networkInterface1);
+ try {
+ mss.leaveGroup(groupSockAddr2, networkInterface1);
+ fail(
+ "Did not get exception when trying to leave group that was never joined");
+ } catch (IOException e) {
+ }
+
+ mss.leaveGroup(groupSockAddr, networkInterface1);
+ if (atLeastTwoInterfaces) {
+ mss.joinGroup(groupSockAddr, networkInterface1);
+ try {
+ mss.leaveGroup(groupSockAddr, networkInterface2);
+ fail(
+ "Did not get exception when trying to leave group on wrong interface joined on ["
+ + networkInterface1
+ + "] left on ["
+ + networkInterface2 + "]");
+ } catch (IOException e) {
+ }
+ }
}
- mss.leaveGroup(groupSockAddr, networkInterface1);
- if (atLeastTwoInterfaces) {
- mss.joinGroup(groupSockAddr, networkInterface1);
- try {
- mss.leaveGroup(groupSockAddr, networkInterface2);
- fail(
- "Did not get exception when trying to leave " +
- "group on wrong interface joined on ["
- + networkInterface1
- + "] left on ["
- + networkInterface2 + "]");
- } catch (IOException e) {
- }
- }
- }
- } catch (Exception e) {
- fail("Exception during leaveGroup test: " + e.toString());
- } finally {
- System.setSecurityManager(null);
- }
- }
+ System.setSecurityManager(null);
+ }
- /**
- * @tests java.net.MulticastSocket#send(java.net.DatagramPacket, byte)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "send",
- args = {java.net.DatagramPacket.class, byte.class}
- )
- public void test_sendLjava_net_DatagramPacketB() throws InterruptedException {
- // Test for method void
- // java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
+ /**
+ * @tests java.net.MulticastSocket#send(java.net.DatagramPacket, byte)
+ */
+ public void test_sendLjava_net_DatagramPacketB() {
+ // Test for method void
+ // java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
- String msg = "Hello World";
- InetAddress group = null;
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
- int groupPort = ports[0];
+ String msg = "Hello World";
+ InetAddress group = null;
+ int[] ports = Support_PortManager.getNextPortsForUDP(2);
+ int groupPort = ports[0];
- try {
- group = InetAddress.getByName("224.0.0.3");
- mss = new MulticastSocket(ports[1]);
- server = new MulticastServer(group, groupPort);
- server.start();
- Thread.sleep(200);
- DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
- .length(), group, groupPort);
- mss.send(sdp, (byte) 10);
- Thread.sleep(1000);
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
- } catch (Exception e) {
- handleException(e, SO_MULTICAST);
- try {
- mss.close();
- } catch (Exception ex) {
- }
-
- return;
- }
-
- DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
- .length(), group, groupPort);
+ try {
+ group = InetAddress.getByName("224.0.0.3");
+ mss = new MulticastSocket(ports[1]);
+ server = new MulticastServer(group, groupPort);
+ server.start();
+ Thread.sleep(200);
+ DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
+ .length(), group, groupPort);
+ mss.send(sdp, (byte) 10);
+ Thread.sleep(1000);
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+ } catch (Exception e) {
+ handleException(e, SO_MULTICAST);
+ try {
+ mss.close();
+ } catch (Exception ex) {
+ }
+ ;
+ return;
+ }
+ mss.close();
+ byte[] data = server.rdp.getData();
+ int length = server.rdp.getLength();
+ assertEquals("Failed to send data. Received " + length,
+ msg, new String(data, 0, length));
+ }
-
- SecurityManager sm = new SecurityManager() {
+ /**
+ * @tests java.net.MulticastSocket#setInterface(java.net.InetAddress)
+ */
+ public void test_setInterfaceLjava_net_InetAddress() throws UnknownHostException {
+ // Test for method void
+ // java.net.MulticastSocket.setInterface(java.net.InetAddress)
+ // Note that the machine is not multi-homed
- public void checkPermission(Permission perm) {
- }
-
- public void checkConnect(String host,
- int port) {
- throw new SecurityException();
- }
-
- public void checkMulticast(InetAddress maddr) {
- throw new SecurityException();
- }
- };
+ try {
+ mss = new MulticastSocket();
+ mss.setInterface(InetAddress.getLocalHost());
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST_INTERFACE);
+ } catch (Exception e) {
+ handleException(e, SO_MULTICAST_INTERFACE);
+ return;
+ }
+ try {
+ InetAddress theInterface = mss.getInterface();
+ // under IPV6 we are not guarrenteed to get the same address back as
+ // the address, all we should be guaranteed is that we get an
+ // address on the same interface
+ if (theInterface instanceof Inet6Address) {
+ assertTrue(
+ "Failed to return correct interface IPV6",
+ NetworkInterface
+ .getByInetAddress(mss.getInterface())
+ .equals(
+ NetworkInterface
+ .getByInetAddress(theInterface)));
+ } else {
+ assertTrue("Failed to return correct interface IPV4 got:"
+ + mss.getInterface() + " excpeted: "
+ + InetAddress.getLocalHost(), mss.getInterface()
+ .equals(InetAddress.getLocalHost()));
+ }
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+ } catch (SocketException e) {
+ handleException(e, SO_MULTICAST);
+ }
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- mss.send(sdp);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (IOException e) {
- fail("IOException was thrown.");
- e.printStackTrace();
- } finally {
- System.setSecurityManager(oldSm);
- }
-
- mss.close();
-
- try {
- mss.send(sdp);
- fail("IOException should be thrown.");
- } catch(IOException ioe) {
- //expected
- }
+ // Regression test for Harmony-2410
+ try {
+ mss = new MulticastSocket();
+ mss.setInterface(InetAddress.getByName("224.0.0.5"));
+ } catch (SocketException se) {
+ // expected
+ } catch (IOException ioe) {
+ handleException(ioe, SO_MULTICAST_INTERFACE);
+ return;
+ }
+ }
- DatagramPacket rdp = server.receive();
- assertEquals("Failed to send data. Received " + rdp.getLength(), msg,
- new String(rdp.getData(), 0, rdp.getLength()));
- }
-
- /**
- * @tests java.net.MulticastSocket#setInterface(java.net.InetAddress)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "setInterface",
- args = {java.net.InetAddress.class}
- )
- public void test_setInterfaceLjava_net_InetAddress() {
- // Test for method void
- // java.net.MulticastSocket.setInterface(java.net.InetAddress)
- // Note that the machine is not multi-homed
-
- try {
- mss = new MulticastSocket();
- mss.setInterface(InetAddress.getLocalHost());
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST_INTERFACE);
- } catch (Exception e) {
- //handleException(e, SO_MULTICAST_INTERFACE);
- return;
- }
- try {
- InetAddress theInterface = mss.getInterface();
- // under IPV6 we are not guarrenteed to get the same address back as
- // the address, all we should be guaranteed is that we get an
- // address on the same interface
- if (theInterface instanceof Inet6Address) {
- assertTrue(
- "Failed to return correct interface IPV6",
- NetworkInterface
- .getByInetAddress(mss.getInterface())
- .equals(
- NetworkInterface
- .getByInetAddress(theInterface)));
- } else {
- assertTrue("Failed to return correct interface IPV4 got:"
- + mss.getInterface() + " excpeted: "
- + InetAddress.getLocalHost(), mss.getInterface()
- .equals(InetAddress.getLocalHost()));
- }
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
- } catch (SocketException e) {
- handleException(e, SO_MULTICAST);
- } catch (UnknownHostException e) {
- fail("Exception during setInterface test: " + e.toString());
- }
-
- // Regression test for Harmony-2410
- try {
- mss = new MulticastSocket();
- mss.setInterface(InetAddress.getByName("224.0.0.5"));
- } catch (UnknownHostException uhe) {
- fail("Unable to get InetAddress by name from '224.0.0.5' addr: "
- + uhe.toString());
- } catch (SocketException se) {
- // expected
- } catch (IOException ioe) {
- handleException(ioe, SO_MULTICAST_INTERFACE);
- return;
- }
- }
-
- /**
- * @throws IOException
- * @throws InterruptedException
- * @tests java.net.MulticastSocket#setNetworkInterface(
- * java.net.NetworkInterface)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "setNetworkInterface",
- args = {java.net.NetworkInterface.class}
- )
- public void test_setNetworkInterfaceLjava_net_NetworkInterface()
- throws IOException, InterruptedException {
- String msg = null;
- InetAddress group = null;
- int[] ports = Support_PortManager.getNextPortsForUDP(2);
- int groupPort = ports[0];
- int serverPort = ports[1];
- if (atLeastOneInterface) {
+ /**
+ * @throws IOException
+ * @throws InterruptedException
+ * @tests java.net.MulticastSocket#setNetworkInterface(java.net.NetworkInterface)
+ */
+ public void test_setNetworkInterfaceLjava_net_NetworkInterface() throws IOException, InterruptedException {
+ String msg = null;
+ InetAddress group = null;
+ int[] ports = Support_PortManager.getNextPortsForUDP(2);
+ int groupPort = ports[0];
+ int serverPort = ports[1];
+ if (atLeastOneInterface) {
// validate that null interface is handled ok
mss = new MulticastSocket(groupPort);
// this should through a socket exception to be compatible
try {
mss.setNetworkInterface(null);
- fail("No socket exception when we set then network " +
- "interface with NULL");
+ fail("No socket exception when we set then network interface with NULL");
} catch (SocketException ex) {
}
@@ -1122,9 +809,8 @@
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
mss.setNetworkInterface(networkInterface1);
- assertTrue(
- "Interface did not seem to be set by setNeworkInterface",
- networkInterface1.equals(mss.getNetworkInterface()));
+ assertEquals("Interface did not seem to be set by setNeworkInterface",
+ networkInterface1, mss.getNetworkInterface());
// set up the server and join the group
group = InetAddress.getByName("224.0.0.3");
@@ -1133,8 +819,7 @@
while (theInterfaces.hasMoreElements()) {
NetworkInterface thisInterface = (NetworkInterface) theInterfaces
.nextElement();
- if (thisInterface.getInetAddresses() != null
- && thisInterface.getInetAddresses().hasMoreElements()) {
+ if (thisInterface.getInetAddresses().hasMoreElements()) {
if ((!((InetAddress) thisInterface.getInetAddresses()
.nextElement()).isLoopbackAddress())
&&
@@ -1163,95 +848,57 @@
DatagramPacket sdp = new DatagramPacket(theBytes,
theBytes.length, group, serverPort);
mss.send(sdp);
- DatagramPacket rdp = server.receive();
-
- String receivedMessage = new String(rdp.getData(), 0, rdp.getLength());
- assertEquals("Group member did not recv data when send on "
- + "a specific interface: ", msg, receivedMessage);
- assertEquals("Datagram was not received as expected.",
- thisInterface, NetworkInterface.getByInetAddress(rdp.getAddress()));
-
+ Thread.sleep(1000);
+ String receivedMessage = new String(server.rdp
+ .getData(), 0, server.rdp.getLength());
+ assertEquals("Group member did not recv data sent on a specific interface",
+ msg, receivedMessage);
// stop the server
server.stopServer();
}
}
}
}
- }
+ }
- /**
- * @tests java.net.MulticastSocket#setTimeToLive(int)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "setTimeToLive",
- args = {int.class}
- )
- public void test_setTimeToLiveI() {
- try {
- mss = new MulticastSocket();
- mss.setTimeToLive(120);
- assertTrue("Returned incorrect 1st TTL: " + mss.getTimeToLive(),
- mss.getTimeToLive() == 120);
- mss.setTimeToLive(220);
- assertTrue("Returned incorrect 2nd TTL: " + mss.getTimeToLive(),
- mss.getTimeToLive() == 220);
- mss.close();
- try {
- mss.setTimeToLive(1);
- fail("IOException was not thrown.");
- }catch(IOException ioe) {
- //expected
- }
-
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
- } catch (Exception e) {
- handleException(e, SO_MULTICAST);
- }
- }
+ /**
+ * @tests java.net.MulticastSocket#setTimeToLive(int)
+ */
+ public void test_setTimeToLiveI() {
+ try {
+ mss = new MulticastSocket();
+ mss.setTimeToLive(120);
+ assertEquals("Returned incorrect 1st TTL",
+ 120, mss.getTimeToLive());
+ mss.setTimeToLive(220);
+ assertEquals("Returned incorrect 2nd TTL",
+ 220, mss.getTimeToLive());
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+ } catch (Exception e) {
+ handleException(e, SO_MULTICAST);
+ }
+ }
- /**
- * @tests java.net.MulticastSocket#setTTL(byte)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "setTTL",
- args = {byte.class}
- )
- public void test_setTTLB() {
- // Test for method void java.net.MulticastSocket.setTTL(byte)
- try {
- mss = new MulticastSocket();
- mss.setTTL((byte) 120);
- assertTrue("Failed to set TTL: " + mss.getTTL(),
- mss.getTTL() == 120);
-
- mss.close();
- try {
- mss.setTTL((byte) 1);
- fail("IOException was not thrown.");
- } catch(IOException ioe) {
- //expected
- }
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
- } catch (Exception e) {
- handleException(e, SO_MULTICAST);
- }
- }
+ /**
+ * @tests java.net.MulticastSocket#setTTL(byte)
+ */
+ public void test_setTTLB() {
+ // Test for method void java.net.MulticastSocket.setTTL(byte)
+ try {
+ mss = new MulticastSocket();
+ mss.setTTL((byte) 120);
+ assertEquals("Failed to set TTL", 120, mss.getTTL());
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
+ } catch (Exception e) {
+ handleException(e, SO_MULTICAST);
+ }
+ }
- /**
- * @tests java.net.MulticastSocket#MulticastSocket(java.net.SocketAddress)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "MulticastSocket",
- args = {java.net.SocketAddress.class}
- )
- public void test_ConstructorLjava_net_SocketAddress() throws Exception {
- MulticastSocket ms = new MulticastSocket((SocketAddress) null);
+ /**
+ * @tests java.net.MulticastSocket#MulticastSocket(java.net.SocketAddress)
+ */
+ public void test_ConstructorLjava_net_SocketAddress() throws Exception {
+ MulticastSocket ms = new MulticastSocket((SocketAddress) null);
assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
&& !ms.isConnected());
ms.bind(new InetSocketAddress(InetAddress.getLocalHost(),
@@ -1285,109 +932,48 @@
InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
MulticastSocket s = new MulticastSocket(addr);
assertTrue(s.getReuseAddress());
-
- InetSocketAddress isa = new InetSocketAddress(InetAddress
- .getLocalHost(), Support_PortManager.getNextPortForUDP());
-
- SecurityManager sm = new SecurityManager() {
+ }
- public void checkPermission(Permission perm) {
- }
-
- public void checkListen(int port) {
- throw new SecurityException();
- }
- };
-
- SecurityManager oldSm = System.getSecurityManager();
- System.setSecurityManager(sm);
- try {
- new MulticastSocket(isa);
- fail("SecurityException should be thrown.");
- } catch (SecurityException e) {
- // expected
- } catch (SocketException e) {
- fail("SocketException was thrown.");
- } catch (IOException e) {
- fail("IOException was thrown.");
- e.printStackTrace();
- } finally {
- System.setSecurityManager(oldSm);
- }
- }
+ /**
+ * @tests java.net.MulticastSocket#getLoopbackMode()
+ */
+ public void test_getLoopbackMode() {
+ try {
+ MulticastSocket ms = new MulticastSocket((SocketAddress) null);
+ assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
+ && !ms.isConnected());
+ ms.getLoopbackMode();
+ assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
+ && !ms.isConnected());
+ ms.close();
+ assertTrue("should be closed", ms.isClosed());
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
+ } catch (IOException e) {
+ handleException(e, SO_USELOOPBACK);
+ }
+ }
- /**
- * @tests java.net.MulticastSocket#getLoopbackMode()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getLoopbackMode",
- args = {}
- )
- public void test_getLoopbackMode() {
- try {
- MulticastSocket ms = new MulticastSocket((SocketAddress) null);
- assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
- && !ms.isConnected());
- ms.getLoopbackMode();
- assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
- && !ms.isConnected());
- ms.close();
- assertTrue("should be closed", ms.isClosed());
- try {
- ms.getLoopbackMode();
- fail("SocketException was not thrown.");
- } catch(SocketException ioe) {
- //expected
- }
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
- } catch (IOException e) {
- handleException(e, SO_USELOOPBACK);
- }
- }
-
- /**
- * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "setLoopbackMode",
- args = {boolean.class}
- )
- public void test_setLoopbackModeZ() {
- try {
- MulticastSocket ms = new MulticastSocket();
- ms.setLoopbackMode(true);
- assertTrue("loopback should be true", ms.getLoopbackMode());
- ms.setLoopbackMode(false);
- assertTrue("loopback should be false", !ms.getLoopbackMode());
- ms.close();
- assertTrue("should be closed", ms.isClosed());
-
- try {
- ms.setLoopbackMode(true);
- fail("SocketException was not thrown.");
- } catch(SocketException se) {
- //expected
- }
-
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
- } catch (IOException e) {
- handleException(e, SO_USELOOPBACK);
- }
- }
+ /**
+ * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
+ */
+ public void test_setLoopbackModeZ() {
+ try {
+ MulticastSocket ms = new MulticastSocket();
+ ms.setLoopbackMode(true);
+ assertTrue("loopback should be true", ms.getLoopbackMode());
+ ms.setLoopbackMode(false);
+ assertTrue("loopback should be false", !ms.getLoopbackMode());
+ ms.close();
+ assertTrue("should be closed", ms.isClosed());
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
+ } catch (IOException e) {
+ handleException(e, SO_USELOOPBACK);
+ }
+ }
/**
* @tests java.net.MulticastSocket#setLoopbackMode(boolean)
*/
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- notes = "SocketException checking missed",
- method = "setLoopbackMode",
- args = {boolean.class}
- )
public void test_setLoopbackModeSendReceive() throws IOException{
final String ADDRESS = "224.1.2.3";
final int PORT = Support_PortManager.getNextPortForUDP();
@@ -1418,120 +1004,99 @@
String recvMessage = new String(recvData, 0, recvDatagram
.getLength());
assertEquals(message, recvMessage);
- } finally {
+ }finally {
if (socket != null)
socket.close();
}
}
- /**
- * @tests java.net.MulticastSocket#setReuseAddress(boolean)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "SocketException checking missesd. Method inherited from " +
- "class java.net.DatagramSocket",
- method = "setReuseAddress",
- args = {boolean.class}
- )
- public void test_setReuseAddressZ() {
- try {
- // test case were we set it to false
- MulticastSocket theSocket1 = null;
- MulticastSocket theSocket2 = null;
- try {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPortForUDP());
- theSocket1 = new MulticastSocket(null);
- theSocket2 = new MulticastSocket(null);
- theSocket1.setReuseAddress(false);
- theSocket2.setReuseAddress(false);
- theSocket1.bind(theAddress);
- theSocket2.bind(theAddress);
- fail(
- "No exception when trying to connect to do " +
- "duplicate socket bind with re-useaddr set to false");
- } catch (BindException e) {
+ /**
+ * @tests java.net.MulticastSocket#setReuseAddress(boolean)
+ */
+ public void test_setReuseAddressZ() throws Exception {
+ try {
+ // test case were we set it to false
+ MulticastSocket theSocket1 = null;
+ MulticastSocket theSocket2 = null;
+ try {
+ InetSocketAddress theAddress = new InetSocketAddress(
+ InetAddress.getLocalHost(), Support_PortManager
+ .getNextPortForUDP());
+ theSocket1 = new MulticastSocket(null);
+ theSocket2 = new MulticastSocket(null);
+ theSocket1.setReuseAddress(false);
+ theSocket2.setReuseAddress(false);
+ theSocket1.bind(theAddress);
+ theSocket2.bind(theAddress);
+ fail(
+ "No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
+ } catch (BindException e) {
- }
- if (theSocket1 != null)
- theSocket1.close();
- if (theSocket2 != null)
- theSocket2.close();
+ }
+ if (theSocket1 != null)
+ theSocket1.close();
+ if (theSocket2 != null)
+ theSocket2.close();
- // test case were we set it to true
- try {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPortForUDP());
- theSocket1 = new MulticastSocket(null);
- theSocket2 = new MulticastSocket(null);
- theSocket1.setReuseAddress(true);
- theSocket2.setReuseAddress(true);
- theSocket1.bind(theAddress);
- theSocket2.bind(theAddress);
- } catch (Exception e) {
- fail(
- "unexpected exception when trying to connect " +
- "to do duplicate socket bind with re-useaddr set " +
- "to true");
- }
- if (theSocket1 != null)
- theSocket1.close();
- if (theSocket2 != null)
- theSocket2.close();
+ // test case were we set it to true
+ InetSocketAddress theAddress = new InetSocketAddress(
+ InetAddress.getLocalHost(), Support_PortManager
+ .getNextPortForUDP());
+ theSocket1 = new MulticastSocket(null);
+ theSocket2 = new MulticastSocket(null);
+ theSocket1.setReuseAddress(true);
+ theSocket2.setReuseAddress(true);
+ theSocket1.bind(theAddress);
+ theSocket2.bind(theAddress);
- // test the default case which we expect to be the same on all
- // platforms
- try {
- InetSocketAddress theAddress = new InetSocketAddress(
- InetAddress.getLocalHost(), Support_PortManager
- .getNextPortForUDP());
- theSocket1 = new MulticastSocket(null);
- theSocket2 = new MulticastSocket(null);
- theSocket1.bind(theAddress);
- theSocket2.bind(theAddress);
- } catch (BindException e) {
- fail(
- "unexpected exception when trying to connect to do " +
- "duplicate socket bind with re-useaddr left as default");
- }
- if (theSocket1 != null)
- theSocket1.close();
- if (theSocket2 != null)
- theSocket2.close();
- ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_REUSEADDR);
- } catch (Exception e) {
- handleException(e, SO_REUSEADDR);
- }
- }
+ if (theSocket1 != null)
+ theSocket1.close();
+ if (theSocket2 != null)
+ theSocket2.close();
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
+ // test the default case which we expect to be
+ // the same on all platforms
+ theAddress =
+ new InetSocketAddress(
+ InetAddress.getLocalHost(),
+ Support_PortManager.getNextPortForUDP());
+ theSocket1 = new MulticastSocket(null);
+ theSocket2 = new MulticastSocket(null);
+ theSocket1.bind(theAddress);
+ theSocket2.bind(theAddress);
+ if (theSocket1 != null)
+ theSocket1.close();
+ if (theSocket2 != null)
+ theSocket2.close();
+ ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_REUSEADDR);
+ } catch (Exception e) {
+ handleException(e, SO_REUSEADDR);
+ }
+ }
- Enumeration theInterfaces = null;
- try {
- theInterfaces = NetworkInterface.getNetworkInterfaces();
- } catch (Exception e) {
- }
+ /**
+ * Sets up the fixture, for example, open a network connection. This method
+ * is called before a test is executed.
+ */
+ protected void setUp() {
- // only consider interfaces that have addresses associated with them.
- // Otherwise tests don't work so well
- if (theInterfaces != null) {
+ Enumeration theInterfaces = null;
+ try {
+ theInterfaces = NetworkInterface.getNetworkInterfaces();
+ } catch (Exception e) {
+ }
- atLeastOneInterface = false;
- while (theInterfaces.hasMoreElements()
+ // only consider interfaces that have addresses associated with them.
+ // Otherwise tests don't work so well
+ if (theInterfaces != null) {
+
+ atLeastOneInterface = false;
+ while (theInterfaces.hasMoreElements()
&& (atLeastOneInterface == false)) {
networkInterface1 = (NetworkInterface) theInterfaces
.nextElement();
- if ((networkInterface1.getInetAddresses() != null)
- && networkInterface1.getInetAddresses()
- .hasMoreElements() &&
+ if (networkInterface1.getInetAddresses().hasMoreElements() &&
// we only want real interfaces
(Support_NetworkInterface
.useInterface(networkInterface1) == true)) {
@@ -1539,15 +1104,14 @@
}
}
- atLeastTwoInterfaces = false;
- if (theInterfaces.hasMoreElements()) {
+ atLeastTwoInterfaces = false;
+ if (theInterfaces.hasMoreElements()) {
while (theInterfaces.hasMoreElements()
&& (atLeastTwoInterfaces == false)) {
networkInterface2 = (NetworkInterface) theInterfaces
.nextElement();
- if ((networkInterface2.getInetAddresses() != null)
- && networkInterface2.getInetAddresses()
- .hasMoreElements() &&
+ if (networkInterface2.getInetAddresses().hasMoreElements()
+ &&
// we only want real interfaces
(Support_NetworkInterface
.useInterface(networkInterface2) == true)) {
@@ -1556,44 +1120,44 @@
}
}
- Enumeration addresses;
+ Enumeration addresses;
- // first the first interface that supports IPV6 if one exists
- try {
- theInterfaces = NetworkInterface.getNetworkInterfaces();
- } catch (Exception e) {
- }
- boolean found = false;
- while (theInterfaces.hasMoreElements() && !found) {
- NetworkInterface nextInterface = (NetworkInterface) theInterfaces
- .nextElement();
- addresses = nextInterface.getInetAddresses();
- if (addresses != null) {
- while (addresses.hasMoreElements()) {
- InetAddress nextAddress = (InetAddress) addresses
- .nextElement();
- if (nextAddress instanceof Inet6Address) {
- IPV6networkInterface1 = nextInterface;
- found = true;
- break;
- }
- }
- }
- }
- }
- }
+ // first the first interface that supports IPV6 if one exists
+ try {
+ theInterfaces = NetworkInterface.getNetworkInterfaces();
+ } catch (Exception e) {
+ }
+ boolean found = false;
+ while (theInterfaces.hasMoreElements() && !found) {
+ NetworkInterface nextInterface = (NetworkInterface) theInterfaces
+ .nextElement();
+ addresses = nextInterface.getInetAddresses();
+ if (addresses.hasMoreElements()) {
+ while (addresses.hasMoreElements()) {
+ InetAddress nextAddress = (InetAddress) addresses
+ .nextElement();
+ if (nextAddress instanceof Inet6Address) {
+ IPV6networkInterface1 = nextInterface;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() throws InterruptedException {
+ /**
+ * Tears down the fixture, for example, close a network connection. This
+ * method is called after a test is executed.
+ */
+ protected void tearDown() {
- if (t != null)
- t.interrupt();
- if (mss != null)
- mss.close();
- if (server != null)
- server.stopServer();
- }
+ if (t != null)
+ t.interrupt();
+ if (mss != null)
+ mss.close();
+ if (server != null)
+ server.stopServer();
+ }
}
diff --git a/luni/src/test/java/tests/api/java/net/ProxySelectorTest.java b/luni/src/test/java/tests/api/java/net/ProxySelectorTest.java
index f208954..ee8195b 100644
--- a/luni/src/test/java/tests/api/java/net/ProxySelectorTest.java
+++ b/luni/src/test/java/tests/api/java/net/ProxySelectorTest.java
@@ -34,6 +34,7 @@
import java.util.Properties;
import junit.framework.TestCase;
+import tests.util.TestEnvironment;
@TestTargetClass(ProxySelector.class)
public class ProxySelectorTest extends TestCase {
@@ -77,11 +78,6 @@
}
}
- /*
- * Original system properties must be restored after running each test case.
- */
- private Properties orignalSystemProperties;
-
/**
* @tests java.net.ProxySelector#getDefault()
*/
@@ -722,16 +718,14 @@
*/
protected void setUp() throws Exception {
super.setUp();
- // save original system properties
- orignalSystemProperties = (Properties) System.getProperties().clone();
+ TestEnvironment.reset();
}
/*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
- // restore orignal system properties
- System.setProperties(orignalSystemProperties);
+ TestEnvironment.reset();
super.tearDown();
}
}
diff --git a/luni/src/test/java/tests/api/java/net/ServerSocketTest.java b/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
index ecdfd01..a750536 100644
--- a/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
+++ b/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
@@ -45,6 +45,7 @@
import tests.support.Support_Configuration;
import tests.support.Support_PortManager;
+import tests.util.TestEnvironment;
@TestTargetClass(value = ServerSocket.class)
public class ServerSocketTest extends SocketTestCase {
@@ -1289,7 +1290,7 @@
* method is called after a test is executed.
*/
protected void tearDown() {
-
+ TestEnvironment.reset();
try {
if (s != null)
s.close();
diff --git a/luni/src/test/java/tests/api/java/net/SocketTest.java b/luni/src/test/java/tests/api/java/net/SocketTest.java
index 7cc31a0..b8184a5 100644
--- a/luni/src/test/java/tests/api/java/net/SocketTest.java
+++ b/luni/src/test/java/tests/api/java/net/SocketTest.java
@@ -501,72 +501,14 @@
args = {}
)
public void test_getInputStream() throws IOException {
- System.setSecurityManager(null);
-
- // Test for method java.io.InputStream java.net.Socket.getInputStream()
- int sport = startServer("SServer getInputStream");
- int portNumber = Support_PortManager.getNextPort();
- s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
- (t = new SServer()).start();
- java.io.InputStream is = s.getInputStream();
+ // Simple fetch test
+ ServerSocket server = new ServerSocket(0);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.getLocalPort());
+ InputStream is = client.getInputStream();
assertNotNull("Failed to get stream", is);
- s.setSoTimeout(6000);
- is.read();
- s.close();
- assertEquals("Invalid after close", -1, is.read());
-
- interrupted = false;
- int portNum = Support_PortManager.getNextPort();
- final ServerSocket ss = new ServerSocket(portNum);
- Socket sock = new Socket(InetAddress.getLocalHost(), portNum);
- Runnable runnable = new Runnable() {
- public void run() {
- try {
- Socket as = ss.accept();
- ss.close();
- as.setSoTimeout(12000);
- InputStream in = as.getInputStream();
- in.read();
- in.close();
- } catch (InterruptedIOException e) {
- interrupted = true;
- } catch (IOException e) {
- }
- }
- };
- Thread thread = new Thread(runnable, "Socket.getInputStream");
- thread.start();
- try {
- do {
- Thread.sleep(200);
- } while (!thread.isAlive());
- } catch (InterruptedException e) {
- }
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- }
- sock.close();
- try {
- sock.getInputStream();
- fail("IOException was not thrown.");
- } catch(IOException ioe) {
- //expected
- }
- int c = 0;
- do {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- }
- if (interrupted) {
- fail("read interrupted");
- }
- if (++c > 4) {
- fail("read call did not exit");
- }
- } while (thread.isAlive());
-
+ is.close();
+ client.close();
+ server.close();
}
/**
diff --git a/luni/src/test/java/tests/api/java/net/UnixSocketTest.java b/luni/src/test/java/tests/api/java/net/UnixSocketTest.java
new file mode 100644
index 0000000..4688e34
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/UnixSocketTest.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// BEGIN android-changed
+package tests.api.java.net;
+//package org.apache.harmony.luni.tests.java.net;
+// END android-changed
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+import junit.framework.TestCase;
+
+public class UnixSocketTest extends TestCase {
+
+ /**
+ * @tests java.net.Socket#getInputStream()
+ */
+ public void test_getInputStream() throws IOException {
+ // Simple read/write test over the IO streams
+ final ServerSocket pingServer = new ServerSocket(0);
+ Runnable runnable = new Runnable() {
+ public void run() {
+ try {
+ Socket worker = pingServer.accept();
+ pingServer.close();
+ InputStream in = worker.getInputStream();
+ in.read();
+ OutputStream out = worker.getOutputStream();
+ out.write(new byte[42]);
+ worker.close();
+ } catch (IOException e) {
+ fail(e.getMessage());
+ }
+ }
+ };
+ Thread thread = new Thread(runnable, "UnixSocket.getInputStream");
+ thread.start();
+
+ Socket pingClient = new Socket(InetAddress.getLocalHost(), pingServer
+ .getLocalPort());
+
+ // Busy wait until the client is connected.
+ int c = 0;
+ while (!pingClient.isConnected()) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ if (++c > 4) {
+ fail("thread is not alive");
+ }
+ }
+
+ // Write some data to the server to provoke it
+ OutputStream out = pingClient.getOutputStream();
+ out.write(new byte[256]);
+
+ InputStream in = pingClient.getInputStream();
+ in.read(new byte[42]);
+ try {
+ in.read();
+ fail("Should throw SocketException");
+ } catch (SocketException e) {
+ // expected
+ }
+ in.close();
+
+ try {
+ in.read();
+ fail("Should throw SocketException");
+ } catch (SocketException e) {
+ // expected
+ }
+ try {
+ in.read(new byte[5]);
+ fail("Should throw SocketException");
+ } catch (SocketException e) {
+ // expected
+ }
+
+ pingClient.close();
+ pingServer.close();
+ }
+
+ public void test_connectLjava_net_SocketAddressI() throws Exception {
+ // Now validate that we get a interrupted exception if we try to connect
+ // to an address on which nobody is accepting connections and the
+ // timeout expired
+ Socket theSocket = new Socket();
+ try {
+ theSocket.connect(new InetSocketAddress(InetAddress.getLocalHost(),
+ 1), 200);
+ fail("No interrupted exception when connecting to address nobody listening on with short timeout 200");
+ } catch (ConnectException e) {
+ // Expected
+ }
+ theSocket.close();
+ }
+
+ public void test_getOutputStream() throws Exception {
+ // Regression test for HARMONY-2934
+ Socket socket = new Socket("127.0.0.1", 0, false);
+ OutputStream o = socket.getOutputStream();
+ try {
+ o.write(1);
+ } catch (SocketException e) {
+ // expected
+ } finally {
+ socket.close();
+ }
+ }
+}
diff --git a/luni/src/test/java/tests/api/java/util/AbstractMapTest.java b/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
index c6a612c..7feb001 100644
--- a/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
+++ b/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
@@ -211,7 +211,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
}
diff --git a/luni/src/test/java/tests/api/java/util/ArrayListTest.java b/luni/src/test/java/tests/api/java/util/ArrayListTest.java
index 8aa77cc..0356731 100644
--- a/luni/src/test/java/tests/api/java/util/ArrayListTest.java
+++ b/luni/src/test/java/tests/api/java/util/ArrayListTest.java
@@ -19,7 +19,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetClass;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,13 +33,13 @@
import tests.support.Support_ListTest;
-@TestTargetClass(ArrayList.class)
+@TestTargetClass(ArrayList.class)
public class ArrayListTest extends junit.framework.TestCase {
List alist;
Object[] objArray;
-
+
/**
* @tests java.util.ArrayList#ArrayList()
*/
@@ -72,7 +72,7 @@
// Test for method java.util.ArrayList(int)
ArrayList al = new ArrayList(5);
assertEquals("Incorrect arrayList created", 0, al.size());
-
+
try {
new ArrayList(-10);
fail("IllegalArgumentException expected");
@@ -130,14 +130,14 @@
assertNull("Should have returned null", alist.get(25));
assertTrue("Should have returned the old item from slot 25", alist
.get(26) == oldItem);
-
+
try {
alist.add(-1, null);
fail("IndexOutOfBoundsException expected");
} catch (IndexOutOfBoundsException e) {
//expected
}
-
+
try {
alist.add(alist.size() + 1, null);
fail("IndexOutOfBoundsException expected");
@@ -198,9 +198,9 @@
assertTrue("Incorrect size: " + alist.size(), alist.size() == 205);
assertNull("Item at slot 100 should be null", alist.get(100));
assertNull("Item at slot 101 should be null", alist.get(101));
- assertEquals("Item at slot 102 should be 'yoink'",
+ assertEquals("Item at slot 102 should be 'yoink'",
"yoink", alist.get(102));
- assertEquals("Item at slot 103 should be 'kazoo'",
+ assertEquals("Item at slot 103 should be 'kazoo'",
"kazoo", alist.get(103));
assertNull("Item at slot 104 should be null", alist.get(104));
alist.addAll(205, listWithNulls);
@@ -228,24 +228,29 @@
}
}
- /**
- * @tests java.util.ArrayList#addAll(int, java.util.Collection)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies IndexOutOfBoundsException.",
- method = "addAll",
- args = {int.class, java.util.Collection.class}
- )
- public void test_addAllILjava_util_Collection_2() {
- // Regression for HARMONY-467
- ArrayList obj = new ArrayList();
- try {
- obj.addAll((int) -1, (Collection) null);
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException e) {
- }
- }
+// BEGIN android-removed
+// The spec does not mandate that IndexOutOfBoundsException be thrown in
+// preference to NullPointerException when the caller desserves both.
+//
+// /**
+// * @tests java.util.ArrayList#addAll(int, java.util.Collection)
+// */
+// @TestTargetNew(
+// level = TestLevel.PARTIAL_COMPLETE,
+// notes = "Verifies IndexOutOfBoundsException.",
+// method = "addAll",
+// args = {int.class, java.util.Collection.class}
+// )
+// public void test_addAllILjava_util_Collection_2() {
+// // Regression for HARMONY-467
+// ArrayList obj = new ArrayList();
+// try {
+// obj.addAll((int) -1, (Collection) null);
+// fail("IndexOutOfBoundsException expected");
+// } catch (IndexOutOfBoundsException e) {
+// }
+// }
+// END android-removed
/**
* @tests java.util.ArrayList#addAll(java.util.Collection)
@@ -287,17 +292,17 @@
.get(101) == i.next());
assertTrue("Item at slot 103 is wrong: " + alist.get(102), alist
.get(102) == i.next());
-
-
+
+
// Regression test for Harmony-3481
ArrayList<Integer> originalList = new ArrayList<Integer>(12);
for (int j = 0; j < 12; j++) {
originalList.add(j);
}
-
+
originalList.remove(0);
originalList.remove(0);
-
+
ArrayList<Integer> additionalList = new ArrayList<Integer>(11);
for (int j = 0; j < 11; j++) {
additionalList.add(j);
@@ -672,7 +677,7 @@
assertTrue("Returned incorrect array: " + i,
retArray[i] == objArray[i]);
}
-
+
String[] strArray = new String[100];
try {
alist.toArray(strArray);
@@ -746,16 +751,16 @@
list.remove(0);
assertEquals(1, list.size());
-
+
ArrayList collection = new ArrayList();
collection.add("1");
collection.add("2");
collection.add("3");
assertEquals(3, collection.size());
-
+
list.addAll(0, collection);
assertEquals(4, list.size());
-
+
list.remove(0);
list.remove(0);
assertEquals(2, list.size());
@@ -769,13 +774,13 @@
collection.add("10");
collection.add("11");
collection.add("12");
-
+
assertEquals(12, collection.size());
-
+
list.addAll(0, collection);
assertEquals(14, list.size());
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -818,7 +823,7 @@
mal.add("f");
mal.add("g");
mal.add("h");
-
+
mal.removeRange(2, 4);
String[] result = new String[6];
@@ -827,30 +832,30 @@
new String[] { "a", "b", "e", "f", "g", "h"}));
}
-
+
/**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
*/
protected void setUp() throws Exception {
super.setUp();
-
+
objArray = new Object[100];
for (int i = 0; i < objArray.length; i++) {
objArray[i] = new Integer(i);
}
-
+
alist = new ArrayList();
for (int i = 0; i < objArray.length; i++) {
alist.add(objArray[i]);
}
}
-
+
@Override
protected void tearDown() throws Exception {
objArray = null;
alist = null;
-
+
super.tearDown();
}
}
diff --git a/luni/src/test/java/tests/api/java/util/CalendarTest.java b/luni/src/test/java/tests/api/java/util/CalendarTest.java
index af43096..285fa56 100644
--- a/luni/src/test/java/tests/api/java/util/CalendarTest.java
+++ b/luni/src/test/java/tests/api/java/util/CalendarTest.java
@@ -900,7 +900,6 @@
args = {}
)
})
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getFirstDayOfWeek() {
Calendar cal = Calendar.getInstance();
@@ -917,7 +916,6 @@
method = "getInstance",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getInstanceLjava_util_Locale() {
Calendar cal1 = Calendar.getInstance(Locale.FRANCE);
Locale.setDefault(Locale.FRANCE);
@@ -946,7 +944,6 @@
method = "getInstance",
args = {java.util.TimeZone.class, java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getInstanceLjava_util_TimeZoneLjava_util_Locale() {
Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT-6"), Locale.FRANCE);
Locale.setDefault(Locale.FRANCE);
@@ -965,7 +962,6 @@
method = "getMinimalDaysInFirstWeek",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getMinimalDaysInFirstWeek() {
Calendar cal = Calendar.getInstance();
assertTrue(cal.getMinimalDaysInFirstWeek()==1);
@@ -1011,7 +1007,6 @@
method = "hashCode",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_hashCode() {
Calendar cal1 = Calendar.getInstance();
Locale.setDefault(Locale.FRANCE);
diff --git a/luni/src/test/java/tests/api/java/util/CollectionsTest.java b/luni/src/test/java/tests/api/java/util/CollectionsTest.java
index 2b1b47e..7fc60d8 100644
--- a/luni/src/test/java/tests/api/java/util/CollectionsTest.java
+++ b/luni/src/test/java/tests/api/java/util/CollectionsTest.java
@@ -41,6 +41,7 @@
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.Arrays;
import org.apache.harmony.luni.internal.nls.Messages;
@@ -807,18 +808,19 @@
LinkedList ll2 = new LinkedList();
ll2.addAll(ll);
testShuffle(ll2, "Random Access", false);
+ }
- Mock_ArrayList mal = new Mock_ArrayList();
-
- mal.add("First");
- mal.add("Second");
-
- try {
- Collections.shuffle(mal);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException e) {
- //expected
- }
+ public void testShuffleRandomAccessWithSeededRandom() {
+ List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F", "G");
+ Collections.shuffle(list, new Random(0));
+ assertEquals(Arrays.asList("B", "A", "D", "C", "G", "E", "F"), list);
+ }
+
+ public void testShuffleWithSeededRandom() {
+ List<String> list = new LinkedList<String>(Arrays.asList(
+ "A", "B", "C", "D", "E", "F", "G"));
+ Collections.shuffle(list, new Random(0));
+ assertEquals(Arrays.asList("B", "A", "D", "C", "G", "E", "F"), list);
}
private void testShuffle(List list, String type, boolean random) {
@@ -837,15 +839,15 @@
sorted = false;
}
}
- assertTrue("Shuffling sorted " + type
- + " list resulted in sorted list (should be unlikely)", !sorted);
+ assertFalse("Shuffling sorted " + type
+ + " list resulted in sorted list (should be unlikely)", sorted);
for (int counter = 0; counter < 20; counter++) {
index = 30031 * counter % (size + 1); // 30031 is a large prime
if (list.get(index) != ll.get(index))
allMatch = false;
}
- assertTrue("Too many element positions match in shuffled " + type
- + " list", !allMatch);
+ assertFalse("Too many element positions match in shuffled " + type
+ + " list", allMatch);
}
/**
diff --git a/luni/src/test/java/tests/api/java/util/FormatterTest.java b/luni/src/test/java/tests/api/java/util/FormatterTest.java
index b2030c9..94113e1 100644
--- a/luni/src/test/java/tests/api/java/util/FormatterTest.java
+++ b/luni/src/test/java/tests/api/java/util/FormatterTest.java
@@ -59,6 +59,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import tests.util.TestEnvironment;
@TestTargetClass(Formatter.class)
public class FormatterTest extends TestCase {
@@ -800,6 +801,36 @@
}
}
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Tests that supplying a Formattable works. See http://code.google.com/p/android/issues/detail?id=1767.",
+ method = "format",
+ args = {}
+ )
+ public void test_Formattable() {
+ Formattable ones = new Formattable() {
+ public void formatTo(Formatter formatter, int flags, int width, int precision) throws IllegalFormatException {
+ try {
+ formatter.out().append("111");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ Formattable twos = new Formattable() {
+ public void formatTo(Formatter formatter, int flags, int width, int precision) throws IllegalFormatException {
+ try {
+ formatter.out().append("222");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+
+ assertEquals("aaa 111?", new Formatter().format("aaa %s?", ones).toString());
+ assertEquals("aaa 111 bbb 222?", new Formatter().format("aaa %s bbb %s?", ones, twos).toString());
+ }
+
/**
* @tests java.util.Formatter#out()
*/
@@ -1238,8 +1269,6 @@
} catch (IllegalFormatPrecisionException e) {
// expected
}
-
- System.setProperty("line.separator", oldSeparator);
}
/**
@@ -1765,7 +1794,6 @@
method = "format",
args = {java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionD() {
final Object[][] triple = {
{ 0, "%d", "0" },
@@ -2030,7 +2058,6 @@
args = {java.lang.String.class, java.lang.Object[].class}
)
@AndroidOnly("ICU data is different from RI data")
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion() {
/*
* Implementation note: For a millisecond date based on Long.MAX_VALUE,
@@ -2808,7 +2835,6 @@
method = "format",
args = {java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLjava_lang_String$LBigInteger() {
final Object[][] tripleD = {
{new BigInteger("123456789012345678901234567890"), "%d", "123456789012345678901234567890"}, //$NON-NLS-2$
@@ -2911,7 +2937,6 @@
method = "format",
args = {java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerPaddingConversion() {
Formatter f = null;
@@ -4028,7 +4053,6 @@
method = "format",
args = {java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Formatting of BigDecimal lost precission sometimes")
public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionE() {
Formatter f = null;
final Object[][] tripleE = {
@@ -4617,7 +4641,6 @@
method = "format",
args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLjava_util_LocaleLjava_lang_StringLjava_lang_Object() {
Double val = new Double(3.14);
Calendar cal = Calendar.getInstance();
@@ -4695,6 +4718,7 @@
* Setup resource files for testing
*/
protected void setUp() throws IOException {
+ TestEnvironment.reset();
notExist = File.createTempFile("notexist", null);
notExist.delete();
@@ -4718,6 +4742,7 @@
* Delete the resource files if they exist
*/
protected void tearDown() {
+ TestEnvironment.reset();
if (notExist.exists()) {
notExist.delete();
}
diff --git a/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java b/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
index c5ccde1..6d2ef74 100644
--- a/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
+++ b/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
@@ -148,7 +148,6 @@
method = "GregorianCalendar",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_ConstructorLjava_util_Locale() {
// Test for method java.util.GregorianCalendar(java.util.Locale)
Date date = new Date();
diff --git a/luni/src/test/java/tests/api/java/util/LocaleTest.java b/luni/src/test/java/tests/api/java/util/LocaleTest.java
index d45c5be..01203a3 100644
--- a/luni/src/test/java/tests/api/java/util/LocaleTest.java
+++ b/luni/src/test/java/tests/api/java/util/LocaleTest.java
@@ -258,7 +258,6 @@
method = "getDisplayCountry",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getDisplayCountryLjava_util_Locale() {
// Test for method java.lang.String
// java.util.Locale.getDisplayCountry(java.util.Locale)
@@ -296,7 +295,6 @@
method = "getDisplayLanguage",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getDisplayLanguageLjava_util_Locale() {
// Test for method java.lang.String
// java.util.Locale.getDisplayLanguage(java.util.Locale)
@@ -329,7 +327,6 @@
method = "getDisplayName",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getDisplayNameLjava_util_Locale() {
// Test for method java.lang.String
// java.util.Locale.getDisplayName(java.util.Locale)
@@ -646,5 +643,3 @@
Locale.setDefault(defaultLocale);
}
}
-
-
diff --git a/luni/src/test/java/tests/api/java/util/ScannerTest.java b/luni/src/test/java/tests/api/java/util/ScannerTest.java
index 84f41d6..ce35005 100644
--- a/luni/src/test/java/tests/api/java/util/ScannerTest.java
+++ b/luni/src/test/java/tests/api/java/util/ScannerTest.java
@@ -2146,7 +2146,6 @@
method = "nextShort",
args = {int.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_nextShortI() throws IOException {
s = new Scanner("123 456");
assertEquals(123, s.nextShort(10));
@@ -2304,7 +2303,6 @@
method = "nextShort",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_nextShort() throws IOException {
s = new Scanner("123 456");
assertEquals(123, s.nextShort());
@@ -2465,7 +2463,6 @@
method = "nextLong",
args = {int.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_nextLongI() throws IOException {
s = new Scanner("123 456");
assertEquals(123, s.nextLong(10));
@@ -2623,7 +2620,6 @@
method = "nextLong",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_nextLong() throws IOException {
s = new Scanner("123 456");
assertEquals(123, s.nextLong());
@@ -4287,7 +4283,6 @@
method = "hasNextShort",
args = {int.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_hasNextShortI() throws IOException {
s = new Scanner("123 456");
assertTrue(s.hasNextShort(10));
@@ -4464,7 +4459,6 @@
method = "hasNextShort",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_hasNextShort() throws IOException {
s = new Scanner("123 456");
assertTrue(s.hasNextShort());
@@ -4692,7 +4686,6 @@
method = "hasNextLong",
args = {int.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_hasNextLongI() throws IOException {
s = new Scanner("123 456");
assertTrue(s.hasNextLong(10));
@@ -4910,7 +4903,6 @@
method = "hasNextLong",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_hasNextLong() throws IOException {
s = new Scanner("123 456");
assertTrue(s.hasNextLong());
@@ -5097,7 +5089,6 @@
method = "hasNextDouble",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_hasNextDouble() throws IOException {
s = new Scanner("123 45\u0666. 123.4 .123 ");
s.useLocale(Locale.ENGLISH);
@@ -5211,7 +5202,6 @@
method = "hasNextBigDecimal",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_hasNextBigDecimal() throws IOException {
s = new Scanner("123 45\u0666. 123.4 .123 ");
s.useLocale(Locale.ENGLISH);
@@ -6344,7 +6334,6 @@
method = "nextDouble",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_nextDouble() throws IOException {
s = new Scanner("123 45\u0666. 123.4 .123 ");
s.useLocale(Locale.ENGLISH);
@@ -6437,7 +6426,6 @@
method = "nextBigDecimal",
args = {}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_nextBigDecimal() throws IOException {
s = new Scanner("123 45\u0666. 123.4 .123 ");
s.useLocale(Locale.ENGLISH);
diff --git a/luni/src/test/java/tests/api/java/util/TimeZoneTest.java b/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
index efdb8a1..86f5b9e 100644
--- a/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
@@ -306,7 +306,6 @@
method = "getDisplayName",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getDisplayNameLjava_util_Locale() {
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
assertEquals("Pacific Standard Time", tz.getDisplayName(new Locale("US")));
@@ -333,7 +332,6 @@
args = {boolean.class, int.class, java.util.Locale.class}
)
@AndroidOnly("fail on RI. See comment below")
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getDisplayNameZILjava_util_Locale() {
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
assertEquals("PST", tz.getDisplayName(false, 0, Locale.US));
@@ -383,6 +381,19 @@
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
+ method = "useDaylightTime",
+ args = {}
+ )
+ public void test_useDaylightTime() {
+ // http://code.google.com/p/android/issues/detail?id=877
+
+ TimeZone asiaTaipei = TimeZone.getTimeZone("Asia/Taipei");
+ assertFalse("Taiwan doesn't use DST", asiaTaipei.useDaylightTime());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
method = "setID",
args = {java.lang.String.class}
)
diff --git a/luni/src/test/resources/libTestLibrary.so b/luni/src/test/resources/libTestLibrary.so
deleted file mode 100755
index 81acfd5..0000000
--- a/luni/src/test/resources/libTestLibrary.so
+++ /dev/null
Binary files differ
diff --git a/math/src/main/java/java/math/BigInt.java b/math/src/main/java/java/math/BigInt.java
index cb7990a..3ba1da2 100644
--- a/math/src/main/java/java/math/BigInt.java
+++ b/math/src/main/java/java/math/BigInt.java
@@ -225,12 +225,6 @@
return a;
}
- public byte[] bigEndianTwosComplement() {
- byte[] a = NativeBN.bn2twosComp(this.bignum, null);
- return a;
- }
-
-
public int sign() {
return NativeBN.sign(this.bignum);
}
@@ -240,9 +234,9 @@
else if (val < 0) NativeBN.BN_set_negative(this.bignum, 1);
}
-
- public boolean twosCompFitsIntoBytes(int byteCnt) {
- return NativeBN.twosCompFitsIntoBytes(this.bignum, byteCnt);
+ public boolean twosCompFitsIntoBytes(int desiredByteCount) {
+ int actualByteCount = (NativeBN.bitLength(this.bignum) + 7) / 8;
+ return actualByteCount <= desiredByteCount;
}
public int bitLength() {
diff --git a/math/src/test/java/tests/api/java/math/BigIntegerTest.java b/math/src/test/java/tests/api/java/math/BigIntegerTest.java
index d04f742..b84aa17 100644
--- a/math/src/test/java/tests/api/java/math/BigIntegerTest.java
+++ b/math/src/test/java/tests/api/java/math/BigIntegerTest.java
@@ -1299,7 +1299,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
}
diff --git a/nio/src/main/java/java/nio/BaseByteBuffer.java b/nio/src/main/java/java/nio/BaseByteBuffer.java
index 009bcb7..a4acc08 100644
--- a/nio/src/main/java/java/nio/BaseByteBuffer.java
+++ b/nio/src/main/java/java/nio/BaseByteBuffer.java
@@ -16,11 +16,9 @@
package java.nio;
-
/**
* Serves as the root of other byte buffer impl classes, implements common
* methods that can be shared by child classes.
- *
*/
abstract class BaseByteBuffer extends ByteBuffer {
@@ -28,42 +26,52 @@
super(capacity);
}
+ @Override
public final CharBuffer asCharBuffer() {
return CharToByteBufferAdapter.wrap(this);
}
+ @Override
public final DoubleBuffer asDoubleBuffer() {
return DoubleToByteBufferAdapter.wrap(this);
}
+ @Override
public final FloatBuffer asFloatBuffer() {
return FloatToByteBufferAdapter.wrap(this);
}
+ @Override
public final IntBuffer asIntBuffer() {
return IntToByteBufferAdapter.wrap(this);
}
+ @Override
public final LongBuffer asLongBuffer() {
return LongToByteBufferAdapter.wrap(this);
}
+ @Override
public final ShortBuffer asShortBuffer() {
return ShortToByteBufferAdapter.wrap(this);
}
+ @Override
public final char getChar() {
return (char) getShort();
}
+ @Override
public final char getChar(int index) {
return (char) getShort(index);
}
+ @Override
public final ByteBuffer putChar(char value) {
return putShort((short) value);
}
+ @Override
public final ByteBuffer putChar(int index, char value) {
return putShort(index, (short) value);
}
diff --git a/nio/src/main/java/java/nio/Buffer.java b/nio/src/main/java/java/nio/Buffer.java
index 19d8969..b4bdc1c 100644
--- a/nio/src/main/java/java/nio/Buffer.java
+++ b/nio/src/main/java/java/nio/Buffer.java
@@ -16,7 +16,6 @@
package java.nio;
-
/**
* A buffer is a list of elements of a specific primitive type.
* <p>
@@ -40,14 +39,10 @@
* take advantage of native memory APIs and it may not stay in the Java heap,
* thus it is not affected by garbage collection.</li>
* </ul>
- * </p>
* <p>
* Buffers are not thread-safe. If concurrent access to a buffer instance is
* required, then the callers are responsible to take care of the
* synchronization issues.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class Buffer {
@@ -125,9 +120,9 @@
/**
* Construct a buffer with the specified capacity.
- *
+ *
* @param capacity
- * the capacity of this buffer.
+ * The capacity of this buffer
*/
Buffer(int capacity) {
super();
@@ -141,7 +136,6 @@
* Returns the capacity of this buffer.
*
* @return the number of elements that are contained in this buffer.
- * @since Android 1.0
*/
public final int capacity() {
return capacity;
@@ -154,10 +148,8 @@
* changes take place: the current position is reset back to the start of
* the buffer, the value of the buffer limit is made equal to the capacity
* and mark is cleared.
- * </p>
- *
+ *
* @return this buffer.
- * @since Android 1.0
*/
public final Buffer clear() {
position = 0;
@@ -171,13 +163,10 @@
* <p>
* The limit is set to the current position, then the position is set to
* zero, and the mark is cleared.
- * </p>
* <p>
* The content of this buffer is not changed.
- * </p>
- *
+ *
* @return this buffer.
- * @since Android 1.0
*/
public final Buffer flip() {
limit = position;
@@ -192,7 +181,6 @@
*
* @return {@code true} if there are elements remaining in this buffer,
* {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasRemaining() {
return position < limit;
@@ -203,7 +191,6 @@
*
* @return {@code true} if this buffer is read-only, {@code false}
* otherwise.
- * @since Android 1.0
*/
public abstract boolean isReadOnly();
@@ -211,7 +198,6 @@
* Returns the limit of this buffer.
*
* @return the limit of this buffer.
- * @since Android 1.0
*/
public final int limit() {
return limit;
@@ -224,15 +210,13 @@
* <code>newLimit</code> then, on returning from this call, it will have
* been adjusted to be equivalent to <code>newLimit</code>. If the mark
* is set and is greater than the new limit, then it is cleared.
- * </p>
- *
+ *
* @param newLimit
* the new limit, must not be negative and not greater than
* capacity.
* @return this buffer.
* @exception IllegalArgumentException
* if <code>newLimit</code> is invalid.
- * @since Android 1.0
*/
public final Buffer limit(int newLimit) {
if (newLimit < 0 || newLimit > capacity) {
@@ -254,7 +238,6 @@
* later by calling <code>reset()</code>.
*
* @return this buffer.
- * @since Android 1.0
*/
public final Buffer mark() {
mark = position;
@@ -265,7 +248,6 @@
* Returns the position of this buffer.
*
* @return the value of this buffer's current position.
- * @since Android 1.0
*/
public final int position() {
return position;
@@ -276,15 +258,13 @@
* <p>
* If the mark is set and it is greater than the new position, then it is
* cleared.
- * </p>
- *
+ *
* @param newPosition
* the new position, must be not negative and not greater than
* limit.
* @return this buffer.
* @exception IllegalArgumentException
* if <code>newPosition</code> is invalid.
- * @since Android 1.0
*/
public final Buffer position(int newPosition) {
if (newPosition < 0 || newPosition > limit) {
@@ -303,7 +283,6 @@
* {@code limit - position}.
*
* @return the number of remaining elements in this buffer.
- * @since Android 1.0
*/
public final int remaining() {
return limit - position;
@@ -315,7 +294,6 @@
* @return this buffer.
* @exception InvalidMarkException
* if the mark is not set.
- * @since Android 1.0
*/
public final Buffer reset() {
if (mark == UNSET_MARK) {
@@ -330,10 +308,8 @@
* <p>
* The position is set to zero, and the mark is cleared. The content of this
* buffer is not changed.
- * </p>
- *
+ *
* @return this buffer.
- * @since Android 1.0
*/
public final Buffer rewind() {
position = 0;
diff --git a/nio/src/main/java/java/nio/BufferFactory.java b/nio/src/main/java/java/nio/BufferFactory.java
index acb2400..94f23ed 100644
--- a/nio/src/main/java/java/nio/BufferFactory.java
+++ b/nio/src/main/java/java/nio/BufferFactory.java
@@ -17,7 +17,6 @@
package java.nio;
-
/**
* Provide factory service of buffer classes.
* <p>
@@ -25,7 +24,6 @@
* this factory is the only entrance to access buffer functions from outside of
* the impl package.
* </p>
- *
*/
final class BufferFactory {
diff --git a/nio/src/main/java/java/nio/BufferOverflowException.java b/nio/src/main/java/java/nio/BufferOverflowException.java
index a9ec60d..a1f7792 100644
--- a/nio/src/main/java/java/nio/BufferOverflowException.java
+++ b/nio/src/main/java/java/nio/BufferOverflowException.java
@@ -16,12 +16,9 @@
package java.nio;
-
/**
* A <code>BufferOverflowException</code> is thrown when elements are written
* to a buffer but there is not enough remaining space in the buffer.
- *
- * @since Android 1.0
*/
public class BufferOverflowException extends RuntimeException {
@@ -29,8 +26,6 @@
/**
* Constructs a <code>BufferOverflowException</code>.
- *
- * @since Android 1.0
*/
public BufferOverflowException() {
super();
diff --git a/nio/src/main/java/java/nio/BufferUnderflowException.java b/nio/src/main/java/java/nio/BufferUnderflowException.java
index f15a8db..14d413b 100644
--- a/nio/src/main/java/java/nio/BufferUnderflowException.java
+++ b/nio/src/main/java/java/nio/BufferUnderflowException.java
@@ -16,12 +16,9 @@
package java.nio;
-
/**
* A <code>BufferUnderflowException</code> is thrown when elements are read
* from a buffer but there are not enough remaining elements in the buffer.
- *
- * @since Android 1.0
*/
public class BufferUnderflowException extends RuntimeException {
@@ -29,8 +26,6 @@
/**
* Constructs a <code>BufferUnderflowException</code>.
- *
- * @since Android 1.0
*/
public BufferUnderflowException() {
super();
diff --git a/nio/src/main/java/java/nio/ByteBuffer.java b/nio/src/main/java/java/nio/ByteBuffer.java
index a033298..821bbed 100644
--- a/nio/src/main/java/java/nio/ByteBuffer.java
+++ b/nio/src/main/java/java/nio/ByteBuffer.java
@@ -17,14 +17,12 @@
package java.nio;
-
import org.apache.harmony.luni.platform.Endianness;
/**
* A buffer for bytes.
* <p>
* A byte buffer can be created in either one of the following ways:
- * </p>
* <ul>
* <li>{@link #allocate(int) Allocate} a new byte array and create a buffer
* based on it;</li>
@@ -33,9 +31,10 @@
* <li>{@link #wrap(byte[]) Wrap} an existing byte array to create a new
* buffer.</li>
* </ul>
- * @since Android 1.0
+ *
*/
-public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
+public abstract class ByteBuffer extends Buffer implements
+ Comparable<ByteBuffer> {
/**
* Creates a byte buffer based on a newly allocated byte array.
@@ -45,7 +44,6 @@
* @return the created byte buffer.
* @throws IllegalArgumentException
* if {@code capacity < 0}.
- * @since Android 1.0
*/
public static ByteBuffer allocate(int capacity) {
if (capacity < 0) {
@@ -62,7 +60,6 @@
* @return the created byte buffer.
* @throws IllegalArgumentException
* if {@code capacity < 0}.
- * @since Android 1.0
*/
public static ByteBuffer allocateDirect(int capacity) {
if (capacity < 0) {
@@ -76,12 +73,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(array, 0, array.length)}.
- * </p>
- *
+ *
* @param array
* the byte array which the new buffer will be based on
* @return the created byte buffer.
- * @since Android 1.0
*/
public static ByteBuffer wrap(byte[] array) {
return BufferFactory.newByteBuffer(array);
@@ -92,8 +87,7 @@
* <p>
* The new buffer's position will be {@code start}, limit will be
* {@code start + len}, capacity will be the length of the array.
- * </p>
- *
+ *
* @param array
* the byte array which the new buffer will be based on.
* @param start
@@ -105,7 +99,6 @@
* @return the created byte buffer.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code len} is invalid.
- * @since Android 1.0
*/
public static ByteBuffer wrap(byte[] array, int start, int len) {
int length = array.length;
@@ -130,7 +123,6 @@
*
* @param capacity
* the capacity of the buffer.
- * @since Android 1.0
*/
ByteBuffer(int capacity) {
super(capacity);
@@ -147,7 +139,6 @@
* if this buffer is based on a read-only array.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final byte[] array() {
return protectedArray();
@@ -159,21 +150,19 @@
* <p>
* The offset is the index of the array which corresponds to the zero
* position of the buffer.
- * </p>
- *
+ *
* @return the offset of the byte array which this buffer is based on.
* @exception ReadOnlyBufferException
* if this buffer is based on a read-only array.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int arrayOffset() {
return protectedArrayOffset();
}
// BEGIN android-added
- @Override
+ @Override
Object _array() {
if (hasArray()) {
return array();
@@ -181,7 +170,7 @@
return null;
}
- @Override
+ @Override
int _arrayOffset() {
if (hasArray()) {
return arrayOffset();
@@ -198,15 +187,12 @@
* of remaining bytes divided by two, and its mark is not set. The new
* buffer's read-only property and byte order are the same as this buffer's.
* The new buffer is direct if this byte buffer is direct.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a char buffer which is based on the content of this byte buffer.
- * @since Android 1.0
*/
public abstract CharBuffer asCharBuffer();
@@ -218,16 +204,13 @@
* of remaining bytes divided by eight, and its mark is not set. The new
* buffer's read-only property and byte order are the same as this buffer's.
* The new buffer is direct if this byte buffer is direct.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a double buffer which is based on the content of this byte
* buffer.
- * @since Android 1.0
*/
public abstract DoubleBuffer asDoubleBuffer();
@@ -239,15 +222,12 @@
* of remaining bytes divided by four, and its mark is not set. The new
* buffer's read-only property and byte order are the same as this buffer's.
* The new buffer is direct if this byte buffer is direct.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a float buffer which is based on the content of this byte buffer.
- * @since Android 1.0
*/
public abstract FloatBuffer asFloatBuffer();
@@ -259,15 +239,12 @@
* of remaining bytes divided by four, and its mark is not set. The new
* buffer's read-only property and byte order are the same as this buffer's.
* The new buffer is direct if this byte buffer is direct.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a int buffer which is based on the content of this byte buffer.
- * @since Android 1.0
*/
public abstract IntBuffer asIntBuffer();
@@ -279,15 +256,12 @@
* of remaining bytes divided by eight, and its mark is not set. The new
* buffer's read-only property and byte order are the same as this buffer's.
* The new buffer is direct if this byte buffer is direct.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a long buffer which is based on the content of this byte buffer.
- * @since Android 1.0
*/
public abstract LongBuffer asLongBuffer();
@@ -297,15 +271,12 @@
* The returned buffer is guaranteed to be a new instance, even if this
* buffer is read-only itself. The new buffer's position, limit, capacity
* and mark are the same as this buffer.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means this
* buffer's change of content will be visible to the new buffer. The two
* buffer's position, limit and mark are independent.
- * </p>
- *
+ *
* @return a read-only version of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer asReadOnlyBuffer();
@@ -317,15 +288,12 @@
* of remaining bytes divided by two, and its mark is not set. The new
* buffer's read-only property and byte order are the same as this buffer's.
* The new buffer is direct if this byte buffer is direct.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a short buffer which is based on the content of this byte buffer.
- * @since Android 1.0
*/
public abstract ShortBuffer asShortBuffer();
@@ -336,12 +304,10 @@
* buffer, starting from position zero. Then the position is set to
* {@code remaining()}; the limit is set to capacity; the mark is
* cleared.
- * </p>
- *
+ *
* @return this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer compact();
@@ -356,7 +322,6 @@
* than {@code other}.
* @exception ClassCastException
* if {@code other} is not a byte buffer.
- * @since Android 1.0
*/
public int compareTo(ByteBuffer otherBuffer) {
int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
@@ -383,15 +348,12 @@
* The duplicated buffer's position, limit, capacity and mark are the same
* as this buffer's. The duplicated buffer's read-only property and byte
* order are the same as this buffer's too.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a duplicated buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer duplicate();
@@ -401,14 +363,13 @@
* If {@code other} is not a byte buffer then {@code false} is returned. Two
* byte buffers are equal if and only if their remaining bytes are exactly
* the same. Position, limit, capacity and mark are not considered.
- * </p>
- *
+ *
* @param other
* the object to compare with this byte buffer.
* @return {@code true} if this byte buffer is equal to {@code other},
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof ByteBuffer)) {
return false;
@@ -435,7 +396,6 @@
* @return the byte at the current position.
* @exception BufferUnderflowException
* if the position is equal or greater than limit.
- * @since Android 1.0
*/
public abstract byte get();
@@ -445,14 +405,12 @@
* <p>
* Calling this method has the same effect as
* {@code get(dest, 0, dest.length)}.
- * </p>
- *
+ *
* @param dest
* the destination byte array.
* @return this buffer.
* @exception BufferUnderflowException
* if {@code dest.length} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public ByteBuffer get(byte[] dest) {
return get(dest, 0, dest.length);
@@ -476,11 +434,10 @@
* if either {@code off} or {@code len} is invalid.
* @exception BufferUnderflowException
* if {@code len} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public ByteBuffer get(byte[] dest, int off, int len) {
int length = dest.length;
- if ((off < 0 ) || (len < 0) || ((long)off + (long)len > length)) {
+ if ((off < 0) || (len < 0) || ((long) off + (long) len > length)) {
throw new IndexOutOfBoundsException();
}
@@ -501,7 +458,6 @@
* @return the byte at the specified index.
* @exception IndexOutOfBoundsException
* if index is invalid.
- * @since Android 1.0
*/
public abstract byte get(int index);
@@ -510,12 +466,10 @@
* <p>
* The 2 bytes starting at the current position are composed into a char
* according to the current byte order and returned.
- * </p>
- *
+ *
* @return the char at the current position.
* @exception BufferUnderflowException
* if the position is greater than {@code limit - 2}.
- * @since Android 1.0
*/
public abstract char getChar();
@@ -525,7 +479,6 @@
* The 2 bytes starting from the specified index are composed into a char
* according to the current byte order and returned. The position is not
* changed.
- * </p>
*
* @param index
* the index, must not be negative and equal or less than
@@ -533,7 +486,6 @@
* @return the char at the specified index.
* @exception IndexOutOfBoundsException
* if {@code index} is invalid.
- * @since Android 1.0
*/
public abstract char getChar(int index);
@@ -542,13 +494,11 @@
* 8.
* <p>
* The 8 bytes starting from the current position are composed into a double
- * according to the current byte order and returned.
- * </p>
- *
+ * according to the current byte order and returned.
+ *
* @return the double at the current position.
* @exception BufferUnderflowException
* if the position is greater than {@code limit - 8}.
- * @since Android 1.0
*/
public abstract double getDouble();
@@ -558,15 +508,13 @@
* The 8 bytes starting at the specified index are composed into a double
* according to the current byte order and returned. The position is not
* changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 8}.
* @return the double at the specified index.
* @exception IndexOutOfBoundsException
* if {@code index} is invalid.
- * @since Android 1.0
*/
public abstract double getDouble(int index);
@@ -576,12 +524,10 @@
* <p>
* The 4 bytes starting at the current position are composed into a float
* according to the current byte order and returned.
- * </p>
- *
+ *
* @return the float at the current position.
* @exception BufferUnderflowException
* if the position is greater than {@code limit - 4}.
- * @since Android 1.0
*/
public abstract float getFloat();
@@ -591,15 +537,13 @@
* The 4 bytes starting at the specified index are composed into a float
* according to the current byte order and returned. The position is not
* changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 4}.
* @return the float at the specified index.
* @exception IndexOutOfBoundsException
* if {@code index} is invalid.
- * @since Android 1.0
*/
public abstract float getFloat(int index);
@@ -608,12 +552,10 @@
* <p>
* The 4 bytes starting at the current position are composed into a int
* according to the current byte order and returned.
- * </p>
- *
+ *
* @return the int at the current position.
* @exception BufferUnderflowException
* if the position is greater than {@code limit - 4}.
- * @since Android 1.0
*/
public abstract int getInt();
@@ -623,15 +565,13 @@
* The 4 bytes starting at the specified index are composed into a int
* according to the current byte order and returned. The position is not
* changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 4}.
* @return the int at the specified index.
* @exception IndexOutOfBoundsException
* if {@code index} is invalid.
- * @since Android 1.0
*/
public abstract int getInt(int index);
@@ -640,12 +580,10 @@
* <p>
* The 8 bytes starting at the current position are composed into a long
* according to the current byte order and returned.
- * </p>
- *
+ *
* @return the long at the current position.
* @exception BufferUnderflowException
* if the position is greater than {@code limit - 8}.
- * @since Android 1.0
*/
public abstract long getLong();
@@ -655,7 +593,6 @@
* The 8 bytes starting at the specified index are composed into a long
* according to the current byte order and returned. The position is not
* changed.
- * </p>
*
* @param index
* the index, must not be negative and equal or less than
@@ -663,7 +600,6 @@
* @return the long at the specified index.
* @exception IndexOutOfBoundsException
* if {@code index} is invalid.
- * @since Android 1.0
*/
public abstract long getLong(int index);
@@ -672,12 +608,10 @@
* <p>
* The 2 bytes starting at the current position are composed into a short
* according to the current byte order and returned.
- * </p>
- *
+ *
* @return the short at the current position.
* @exception BufferUnderflowException
* if the position is greater than {@code limit - 2}.
- * @since Android 1.0
*/
public abstract short getShort();
@@ -687,15 +621,13 @@
* The 2 bytes starting at the specified index are composed into a short
* according to the current byte order and returned. The position is not
* changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 2}.
* @return the short at the specified index.
* @exception IndexOutOfBoundsException
* if {@code index} is invalid.
- * @since Android 1.0
*/
public abstract short getShort(int index);
@@ -705,7 +637,6 @@
*
* @return {@code true} if this buffer is based on a byte array and provides
* read/write access, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasArray() {
return protectedHasArray();
@@ -714,10 +645,10 @@
/**
* Calculates this buffer's hash code from the remaining chars. The
* position, limit, capacity and mark don't affect the hash code.
- *
+ *
* @return the hash code calculated from the remaining bytes.
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int myPosition = position;
int hash = 0;
@@ -729,9 +660,8 @@
/**
* Indicates whether this buffer is direct.
- *
+ *
* @return {@code true} if this buffer is direct, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isDirect();
@@ -741,11 +671,9 @@
* <p>
* The default byte order of byte buffer is always
* {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
- * </p>
- *
+ *
* @return the byte order used by this buffer when converting bytes from/to
* other primitive types.
- * @since Android 1.0
*/
public final ByteOrder order() {
return order == Endianness.BIG_ENDIAN ? ByteOrder.BIG_ENDIAN
@@ -760,7 +688,6 @@
* will be {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}.
* @return this buffer.
* @see ByteOrder
- * @since Android 1.0
*/
public final ByteBuffer order(ByteOrder byteOrder) {
return orderImpl(byteOrder);
@@ -776,7 +703,6 @@
* Child class implements this method to realize {@code array()}.
*
* @see #array()
- * @since Android 1.0
*/
abstract byte[] protectedArray();
@@ -784,7 +710,6 @@
* Child class implements this method to realize {@code arrayOffset()}.
*
* @see #arrayOffset()
- * @since Android 1.0
*/
abstract int protectedArrayOffset();
@@ -792,7 +717,6 @@
* Child class implements this method to realize {@code hasArray()}.
*
* @see #hasArray()
- * @since Android 1.0
*/
abstract boolean protectedHasArray();
@@ -807,7 +731,6 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer put(byte b);
@@ -817,8 +740,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(src, 0, src.length)}.
- * </p>
- *
+ *
* @param src
* the source byte array.
* @return this buffer.
@@ -826,7 +748,6 @@
* if {@code remaining()} is less than {@code src.length}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final ByteBuffer put(byte[] src) {
return put(src, 0, src.length);
@@ -852,7 +773,6 @@
* if either {@code off} or {@code len} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public ByteBuffer put(byte[] src, int off, int len) {
int length = src.length;
@@ -884,7 +804,6 @@
* if {@code src} is this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public ByteBuffer put(ByteBuffer src) {
if (src == this) {
@@ -912,7 +831,6 @@
* if {@code index} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer put(int index, byte b);
@@ -921,8 +839,7 @@
* by 2.
* <p>
* The char is converted to bytes using the current byte order.
- * </p>
- *
+ *
* @param value
* the char to write.
* @return this buffer.
@@ -930,7 +847,6 @@
* if position is greater than {@code limit - 2}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putChar(char value);
@@ -939,8 +855,7 @@
* <p>
* The char is converted to bytes using the current byte order. The position
* is not changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 2}.
@@ -951,7 +866,6 @@
* if {@code index} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putChar(int index, char value);
@@ -960,8 +874,7 @@
* by 8.
* <p>
* The double is converted to bytes using the current byte order.
- * </p>
- *
+ *
* @param value
* the double to write.
* @return this buffer.
@@ -969,7 +882,6 @@
* if position is greater than {@code limit - 8}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putDouble(double value);
@@ -978,8 +890,7 @@
* <p>
* The double is converted to bytes using the current byte order. The
* position is not changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 8}.
@@ -990,7 +901,6 @@
* if {@code index} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putDouble(int index, double value);
@@ -999,8 +909,7 @@
* by 4.
* <p>
* The float is converted to bytes using the current byte order.
- * </p>
- *
+ *
* @param value
* the float to write.
* @return this buffer.
@@ -1008,7 +917,6 @@
* if position is greater than {@code limit - 4}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putFloat(float value);
@@ -1017,8 +925,7 @@
* <p>
* The float is converted to bytes using the current byte order. The
* position is not changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 4}.
@@ -1029,7 +936,6 @@
* if {@code index} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putFloat(int index, float value);
@@ -1038,8 +944,7 @@
* 4.
* <p>
* The int is converted to bytes using the current byte order.
- * </p>
- *
+ *
* @param value
* the int to write.
* @return this buffer.
@@ -1047,7 +952,6 @@
* if position is greater than {@code limit - 4}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putInt(int value);
@@ -1056,8 +960,7 @@
* <p>
* The int is converted to bytes using the current byte order. The position
* is not changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 4}.
@@ -1068,7 +971,6 @@
* if {@code index} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putInt(int index, int value);
@@ -1077,8 +979,7 @@
* by 8.
* <p>
* The long is converted to bytes using the current byte order.
- * </p>
- *
+ *
* @param value
* the long to write.
* @return this buffer.
@@ -1086,7 +987,6 @@
* if position is greater than {@code limit - 8}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putLong(long value);
@@ -1095,8 +995,7 @@
* <p>
* The long is converted to bytes using the current byte order. The position
* is not changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 8}.
@@ -1107,7 +1006,6 @@
* if {@code index} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putLong(int index, long value);
@@ -1116,8 +1014,7 @@
* by 2.
* <p>
* The short is converted to bytes using the current byte order.
- * </p>
- *
+ *
* @param value
* the short to write.
* @return this buffer.
@@ -1125,7 +1022,6 @@
* if position is greater than {@code limit - 2}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putShort(short value);
@@ -1134,8 +1030,7 @@
* <p>
* The short is converted to bytes using the current byte order. The
* position is not changed.
- * </p>
- *
+ *
* @param index
* the index, must not be negative and equal or less than
* {@code limit - 2}.
@@ -1146,7 +1041,6 @@
* if {@code index} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer putShort(int index, short value);
@@ -1158,15 +1052,12 @@
* this buffer's current position. The new buffer's position will be 0,
* limit will be its capacity, and its mark is cleared. The new buffer's
* read-only property and byte order are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a sliced buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract ByteBuffer slice();
@@ -1174,10 +1065,10 @@
* Returns a string representing the state of this byte buffer.
*
* @return a string representing the state of this byte buffer.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append(getClass().getName());
buf.append(", status: capacity="); //$NON-NLS-1$
buf.append(capacity());
diff --git a/nio/src/main/java/java/nio/ByteOrder.java b/nio/src/main/java/java/nio/ByteOrder.java
index 870216f..c7c92ee 100644
--- a/nio/src/main/java/java/nio/ByteOrder.java
+++ b/nio/src/main/java/java/nio/ByteOrder.java
@@ -16,27 +16,20 @@
package java.nio;
-
import org.apache.harmony.luni.platform.Platform;
/**
* Defines byte order constants.
- *
- * @since Android 1.0
*/
public final class ByteOrder {
/**
* This constant represents big endian.
- *
- * @since Android 1.0
*/
public static final ByteOrder BIG_ENDIAN = new ByteOrder("BIG_ENDIAN"); //$NON-NLS-1$
/**
* This constant represents little endian.
- *
- * @since Android 1.0
*/
public static final ByteOrder LITTLE_ENDIAN = new ByteOrder("LITTLE_ENDIAN"); //$NON-NLS-1$
@@ -55,7 +48,6 @@
*
* @return the byte order object, which is either LITTLE_ENDIAN or
* BIG_ENDIAN.
- * @since Android 1.0
*/
public static ByteOrder nativeOrder() {
return NATIVE_ORDER;
@@ -74,8 +66,8 @@
* @return "BIG_ENDIAN" for {@link #BIG_ENDIAN ByteOrder.BIG_ENDIAN}
* objects, "LITTLE_ENDIAN" for
* {@link #LITTLE_ENDIAN ByteOrder.LITTLE_ENDIAN} objects.
- * @since Android 1.0
*/
+ @Override
public String toString() {
return name;
}
diff --git a/nio/src/main/java/java/nio/CharArrayBuffer.java b/nio/src/main/java/java/nio/CharArrayBuffer.java
index 516aada..0228eb7 100644
--- a/nio/src/main/java/java/nio/CharArrayBuffer.java
+++ b/nio/src/main/java/java/nio/CharArrayBuffer.java
@@ -49,6 +49,7 @@
this.offset = offset;
}
+ @Override
public final char get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -56,6 +57,7 @@
return backingArray[offset + position++];
}
+ @Override
public final char get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -63,38 +65,43 @@
return backingArray[offset + index];
}
+ @Override
public final CharBuffer get(char[] dest, int off, int len) {
int length = dest.length;
- if ((off < 0 ) || (len < 0) || (long)off + (long)len > length) {
+ if ((off < 0) || (len < 0) || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferUnderflowException();
}
- System.arraycopy(backingArray, offset+position, dest, off, len);
+ System.arraycopy(backingArray, offset + position, dest, off, len);
position += len;
return this;
}
-
+
+ @Override
public final boolean isDirect() {
return false;
}
+ @Override
public final ByteOrder order() {
return ByteOrder.nativeOrder();
}
+ @Override
public final CharSequence subSequence(int start, int end) {
if (start < 0 || end < start || end > remaining()) {
throw new IndexOutOfBoundsException();
}
-
+
CharBuffer result = duplicate();
result.limit(position + end);
result.position(position + start);
return result;
}
+ @Override
public final String toString() {
return String.copyValueOf(backingArray, offset + position, remaining());
}
diff --git a/nio/src/main/java/java/nio/CharBuffer.java b/nio/src/main/java/java/nio/CharBuffer.java
index 289965a..4506614 100644
--- a/nio/src/main/java/java/nio/CharBuffer.java
+++ b/nio/src/main/java/java/nio/CharBuffer.java
@@ -23,7 +23,6 @@
* A buffer of chars.
* <p>
* A char buffer can be created in either one of the following ways:
- * </p>
* <ul>
* <li>{@link #allocate(int) Allocate} a new char array and create a buffer
* based on it;</li>
@@ -34,11 +33,9 @@
* <li>Use {@link java.nio.ByteBuffer#asCharBuffer() ByteBuffer.asCharBuffer}
* to create a char buffer based on a byte buffer.</li>
* </ul>
- *
- * @since Android 1.0
*/
-public abstract class CharBuffer extends Buffer implements Comparable<CharBuffer>,
- CharSequence, Appendable, Readable {
+public abstract class CharBuffer extends Buffer implements
+ Comparable<CharBuffer>, CharSequence, Appendable, Readable {
/**
* Creates a char buffer based on a newly allocated char array.
@@ -48,7 +45,6 @@
* @return the created char buffer.
* @throws IllegalArgumentException
* if {@code capacity} is less than zero.
- * @since Android 1.0
*/
public static CharBuffer allocate(int capacity) {
if (capacity < 0) {
@@ -62,12 +58,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(array, 0, array.length)}.
- * </p>
- *
+ *
* @param array
* the char array which the new buffer will be based on.
* @return the created char buffer.
- * @since Android 1.0
*/
public static CharBuffer wrap(char[] array) {
return wrap(array, 0, array.length);
@@ -78,8 +72,7 @@
* <p>
* The new buffer's position will be {@code start}, limit will be
* {@code start + len}, capacity will be the length of the array.
- * </p>
- *
+ *
* @param array
* the char array which the new buffer will be based on.
* @param start
@@ -91,12 +84,10 @@
* @return the created char buffer.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code len} is invalid.
- * @since Android 1.0
*/
public static CharBuffer wrap(char[] array, int start, int len) {
int length = array.length;
- if ((start < 0) || (len < 0)
- || (long) start + (long) len > length) {
+ if ((start < 0) || (len < 0) || (long) start + (long) len > length) {
throw new IndexOutOfBoundsException();
}
@@ -112,12 +103,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(chseq, 0, chseq.length())}.
- * </p>
- *
+ *
* @param chseq
* the char sequence which the new buffer will be based on.
* @return the created char buffer.
- * @since Android 1.0
*/
public static CharBuffer wrap(CharSequence chseq) {
return BufferFactory.newCharBuffer(chseq);
@@ -129,8 +118,7 @@
* The new buffer's position will be {@code start}, limit will be
* {@code end}, capacity will be the length of the char sequence. The new
* buffer is read-only.
- * </p>
- *
+ *
* @param chseq
* the char sequence which the new buffer will be based on.
* @param start
@@ -142,7 +130,6 @@
* @return the created char buffer.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code end} is invalid.
- * @since Android 1.0
*/
public static CharBuffer wrap(CharSequence chseq, int start, int end) {
if (chseq == null) {
@@ -151,7 +138,7 @@
if (start < 0 || end < start || end > chseq.length()) {
throw new IndexOutOfBoundsException();
}
-
+
CharBuffer result = BufferFactory.newCharBuffer(chseq);
result.position = start;
result.limit = end;
@@ -163,7 +150,6 @@
*
* @param capacity
* the capacity of the buffer.
- * @since Android 1.0
*/
CharBuffer(int capacity) {
super(capacity);
@@ -180,7 +166,6 @@
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final char[] array() {
return protectedArray();
@@ -192,21 +177,19 @@
* <p>
* The offset is the index of the array corresponds to the zero position of
* the buffer.
- * </p>
- *
+ *
* @return the offset of the char array which this buffer is based on.
* @exception ReadOnlyBufferException
* if this buffer is based on an array but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int arrayOffset() {
return protectedArrayOffset();
}
// BEGIN android-added
- @Override
+ @Override
Object _array() {
if (hasArray()) {
return array();
@@ -214,7 +197,7 @@
return null;
}
- @Override
+ @Override
int _arrayOffset() {
if (hasArray()) {
return arrayOffset();
@@ -229,15 +212,12 @@
* The returned buffer is guaranteed to be a new instance, even if this
* buffer is read-only itself. The new buffer's position, limit, capacity
* and mark are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means this
* buffer's change of content will be visible to the new buffer. The two
* buffer's position, limit and mark are independent.
- * </p>
- *
+ *
* @return a read-only version of this buffer.
- * @since Android 1.0
*/
public abstract CharBuffer asReadOnlyBuffer();
@@ -253,7 +233,6 @@
* current position) in the buffer.
* @exception IndexOutOfBoundsException
* if the index is invalid.
- * @since Android 1.0
*/
public final char charAt(int index) {
if (index < 0 || index >= remaining()) {
@@ -268,12 +247,10 @@
* The remaining chars will be moved to the head of the buffer,
* starting from position zero. Then the position is set to
* {@code remaining()}; the limit is set to capacity; the mark is cleared.
- * </p>
- *
+ *
* @return this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract CharBuffer compact();
@@ -288,7 +265,6 @@
* greater than {@code otherBuffer}.
* @exception ClassCastException
* if {@code otherBuffer} is not a char buffer.
- * @since Android 1.0
*/
public int compareTo(CharBuffer otherBuffer) {
int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
@@ -315,15 +291,12 @@
* The duplicated buffer's initial position, limit, capacity and mark are
* the same as this buffer's. The duplicated buffer's read-only property and
* byte order are the same as this buffer's, too.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a duplicated buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract CharBuffer duplicate();
@@ -333,14 +306,13 @@
* If {@code other} is not a char buffer then {@code false} is returned. Two
* char buffers are equal if and only if their remaining chars are exactly
* the same. Position, limit, capacity and mark are not considered.
- * </p>
- *
+ *
* @param other
* the object to compare with this char buffer.
* @return {@code true} if this char buffer is equal to {@code other},
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof CharBuffer)) {
return false;
@@ -367,7 +339,6 @@
* @return the char at the current position.
* @exception BufferUnderflowException
* if the position is equal or greater than limit.
- * @since Android 1.0
*/
public abstract char get();
@@ -377,14 +348,12 @@
* <p>
* Calling this method has the same effect as
* {@code get(dest, 0, dest.length)}.
- * </p>
- *
+ *
* @param dest
* the destination char array.
* @return this buffer.
* @exception BufferUnderflowException
* if {@code dest.length} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public CharBuffer get(char[] dest) {
return get(dest, 0, dest.length);
@@ -408,14 +377,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception BufferUnderflowException
* if {@code len} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public CharBuffer get(char[] dest, int off, int len) {
int length = dest.length;
- if ((off < 0 ) || (len < 0) || (long)off + (long)len > length) {
+ if ((off < 0) || (len < 0) || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferUnderflowException();
}
@@ -433,16 +401,14 @@
* @return a char at the specified index.
* @exception IndexOutOfBoundsException
* if index is invalid.
- * @since Android 1.0
*/
public abstract char get(int index);
/**
* Indicates whether this buffer is based on a char array and is read/write.
- *
+ *
* @return {@code true} if this buffer is based on a byte array and provides
* read/write access, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasArray() {
return protectedHasArray();
@@ -451,10 +417,10 @@
/**
* Calculates this buffer's hash code from the remaining chars. The
* position, limit, capacity and mark don't affect the hash code.
- *
+ *
* @return the hash code calculated from the remaining chars.
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int myPosition = position;
int hash = 0;
@@ -471,10 +437,8 @@
* <p>
* A char buffer is direct if it is based on a byte buffer and the byte
* buffer is direct.
- * </p>
- *
+ *
* @return {@code true} if this buffer is direct, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isDirect();
@@ -482,7 +446,6 @@
* Returns the number of remaining chars.
*
* @return the number of remaining chars.
- * @since Android 1.0
*/
public final int length() {
return remaining();
@@ -494,11 +457,9 @@
* <p>
* If this buffer is not based on a byte buffer, then this always returns
* the platform's native byte order.
- * </p>
- *
+ *
* @return the byte order used by this buffer when converting chars from/to
* bytes.
- * @since Android 1.0
*/
public abstract ByteOrder order();
@@ -534,7 +495,6 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract CharBuffer put(char c);
@@ -544,8 +504,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(src, 0, src.length)}.
- * </p>
- *
+ *
* @param src
* the source char array.
* @return this buffer.
@@ -553,7 +512,6 @@
* if {@code remaining()} is less than {@code src.length}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final CharBuffer put(char[] src) {
return put(src, 0, src.length);
@@ -579,14 +537,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public CharBuffer put(char[] src, int off, int len) {
int length = src.length;
- if ((off < 0 ) || (len < 0) || (long)off + (long)len > length) {
+ if ((off < 0) || (len < 0) || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferOverflowException();
}
@@ -611,7 +568,6 @@
* if {@code src} is this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public CharBuffer put(CharBuffer src) {
if (src == this) {
@@ -620,7 +576,7 @@
if (src.remaining() > remaining()) {
throw new BufferOverflowException();
}
-
+
char[] contents = new char[src.remaining()];
src.get(contents);
put(contents);
@@ -640,7 +596,6 @@
* if index is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract CharBuffer put(int index, char c);
@@ -650,8 +605,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(str, 0, str.length())}.
- * </p>
- *
+ *
* @param str
* the string to write.
* @return this buffer.
@@ -659,7 +613,6 @@
* if {@code remaining()} is less than the length of string.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final CharBuffer put(String str) {
return put(str, 0, str.length());
@@ -684,14 +637,13 @@
* if either {@code start} or {@code end} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public CharBuffer put(String str, int start, int end) {
int length = str.length();
if (start < 0 || end < start || end > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (end - start > remaining()) {
throw new BufferOverflowException();
}
@@ -709,15 +661,12 @@
* The new buffer's position will be 0, limit will be its capacity, and its
* mark is cleared. The new buffer's read-only property and byte order are
* same as this buffer.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a sliced buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract CharBuffer slice();
@@ -729,13 +678,11 @@
* be {@code position() + end}, capacity will be the same as this buffer.
* The new buffer's read-only property and byte order are the same as this
* buffer.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @param start
* the start index of the sub-sequence, referenced from the
* current buffer position. Must not be less than zero and not
@@ -750,7 +697,6 @@
* current remaining content.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code end} is invalid.
- * @since Android 1.0
*/
public abstract CharSequence subSequence(int start, int end);
@@ -758,8 +704,8 @@
* Returns a string representing the current remaining chars of this buffer.
*
* @return a string representing the current remaining chars of this buffer.
- * @since Android 1.0
*/
+ @Override
public String toString() {
StringBuffer strbuf = new StringBuffer();
for (int i = position; i < limit; i++) {
@@ -771,7 +717,7 @@
/**
* Writes the given char to the current position and increases the position
* by 1.
- *
+ *
* @param c
* the char to write.
* @return this buffer.
@@ -779,9 +725,8 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
- public CharBuffer append(char c){
+ public CharBuffer append(char c) {
return put(c);
}
@@ -791,10 +736,9 @@
* of the csq.
* <p>
* Calling this method has the same effect as {@code append(csq.toString())}.
- * </p>
* If the {@code CharSequence} is {@code null} the string "null" will be
* written to the buffer.
- *
+ *
* @param csq
* the {@code CharSequence} to write.
* @return this buffer.
@@ -802,9 +746,8 @@
* if {@code remaining()} is less than the length of csq.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
- public CharBuffer append(CharSequence csq){
+ public CharBuffer append(CharSequence csq) {
if (csq != null) {
return put(csq.toString());
}
@@ -814,7 +757,7 @@
/**
* Writes chars of the given {@code CharSequence} to the current position of
* this buffer, and increases the position by the number of chars written.
- *
+ *
* @param csq
* the {@code CharSequence} to write.
* @param start
@@ -830,9 +773,8 @@
* if either {@code start} or {@code end} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
- public CharBuffer append(CharSequence csq, int start, int end){
+ public CharBuffer append(CharSequence csq, int start, int end) {
if (csq == null) {
csq = "null"; //$NON-NLS-1$
}
@@ -848,7 +790,7 @@
* number of chars that are copied is either the number of remaining chars
* in this buffer or the number of remaining chars in {@code target},
* whichever is smaller.
- *
+ *
* @param target
* the target char buffer.
* @throws IllegalArgumentException
@@ -859,19 +801,24 @@
* if no changes may be made to the contents of {@code target}.
* @return the number of chars copied or -1 if there are no chars left to be
* read from this buffer.
- * @since Android 1.0
*/
public int read(CharBuffer target) throws IOException {
- if(target == this){
+ int remaining = remaining();
+ if (target == this) {
+ if (remaining == 0) {
+ return -1;
+ }
throw new IllegalArgumentException();
}
- if (remaining() == 0) {
- return target.remaining()==0?0:-1;
+ if (remaining == 0) {
+ return limit > 0 && target.remaining() == 0 ? 0 : -1;
}
- int result = Math.min(target.remaining(), remaining());
- char[] chars = new char[result];
- get(chars);
- target.put(chars);
- return result;
- }
+ remaining = Math.min(target.remaining(), remaining);
+ if (remaining > 0) {
+ char[] chars = new char[remaining];
+ get(chars);
+ target.put(chars);
+ }
+ return remaining;
+ }
}
diff --git a/nio/src/main/java/java/nio/CharSequenceAdapter.java b/nio/src/main/java/java/nio/CharSequenceAdapter.java
index 32edc18..3f738b2 100644
--- a/nio/src/main/java/java/nio/CharSequenceAdapter.java
+++ b/nio/src/main/java/java/nio/CharSequenceAdapter.java
@@ -44,18 +44,22 @@
sequence = chseq;
}
+ @Override
public CharBuffer asReadOnlyBuffer() {
return duplicate();
}
+ @Override
public CharBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public CharBuffer duplicate() {
return copy(this);
}
+ @Override
public char get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -63,6 +67,7 @@
return sequence.charAt(position++);
}
+ @Override
public char get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -70,9 +75,10 @@
return sequence.charAt(index);
}
+ @Override
public final CharBuffer get(char[] dest, int off, int len) {
int length = dest.length;
- if ((off < 0 ) || (len < 0) || (long)off + (long)len > length) {
+ if ((off < 0) || (len < 0) || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
@@ -84,66 +90,79 @@
return this;
}
+ @Override
public boolean isDirect() {
return false;
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
public ByteOrder order() {
return ByteOrder.nativeOrder();
}
+ @Override
protected char[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public CharBuffer put(char c) {
throw new ReadOnlyBufferException();
}
+ @Override
public CharBuffer put(int index, char c) {
throw new ReadOnlyBufferException();
}
+ @Override
public final CharBuffer put(char[] src, int off, int len) {
- if ((off < 0 ) || (len < 0) || (long)off + (long)len > src.length) {
+ if ((off < 0) || (len < 0) || (long) off + (long) len > src.length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferOverflowException();
}
-
+
throw new ReadOnlyBufferException();
}
+ @Override
public CharBuffer put(String src, int start, int end) {
- if ((start < 0 ) || (end < 0) || (long)start + (long)end > src.length()) {
+ if ((start < 0) || (end < 0)
+ || (long) start + (long) end > src.length()) {
throw new IndexOutOfBoundsException();
}
throw new ReadOnlyBufferException();
- }
+ }
+ @Override
public CharBuffer slice() {
return new CharSequenceAdapter(sequence.subSequence(position, limit));
}
+ @Override
public CharSequence subSequence(int start, int end) {
if (end < start || start < 0 || end > remaining()) {
throw new IndexOutOfBoundsException();
}
-
+
CharSequenceAdapter result = copy(this);
result.position = position + start;
result.limit = position + end;
diff --git a/nio/src/main/java/java/nio/CharToByteBufferAdapter.java b/nio/src/main/java/java/nio/CharToByteBufferAdapter.java
index bd340be..e92ea57 100644
--- a/nio/src/main/java/java/nio/CharToByteBufferAdapter.java
+++ b/nio/src/main/java/java/nio/CharToByteBufferAdapter.java
@@ -16,11 +16,8 @@
package java.nio;
-// BEGIN android-added
-// Copied from newer version of harmony
import org.apache.harmony.nio.internal.DirectBuffer;
import org.apache.harmony.luni.platform.PlatformAddress;
-// END android-added
/**
* This class wraps a byte buffer to be a char buffer.
@@ -35,10 +32,7 @@
* </p>
*
*/
-// BEGIN android-changed
-// Copied from newer version of harmony
final class CharToByteBufferAdapter extends CharBuffer implements DirectBuffer {
-// END android-changed
static CharBuffer wrap(ByteBuffer byteBuffer) {
return new CharToByteBufferAdapter(byteBuffer.slice());
@@ -51,18 +45,15 @@
this.byteBuffer = byteBuffer;
this.byteBuffer.clear();
}
-
- // BEGIN android-added
- // Copied from newer version of harmony
+
public int getByteCapacity() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getByteCapacity();
- } else {
- assert false : byteBuffer;
- return -1;
- }
+ return ((DirectBuffer) byteBuffer).getByteCapacity();
+ }
+ assert false : byteBuffer;
+ return -1;
}
-
+
public PlatformAddress getEffectiveAddress() {
if (byteBuffer instanceof DirectBuffer) {
// BEGIN android-changed
@@ -70,47 +61,44 @@
effectiveDirectAddress = addr.toInt();
return addr;
// END android-changed
- } else {
- assert false : byteBuffer;
- return null;
}
+ assert false : byteBuffer;
+ return null;
}
public PlatformAddress getBaseAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getBaseAddress();
- } else {
- assert false : byteBuffer;
- return null;
+ return ((DirectBuffer) byteBuffer).getBaseAddress();
}
+ assert false : byteBuffer;
+ return null;
}
-
+
public boolean isAddressValid() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).isAddressValid();
- } else {
- assert false : byteBuffer;
- return false;
+ return ((DirectBuffer) byteBuffer).isAddressValid();
}
+ assert false : byteBuffer;
+ return false;
}
public void addressValidityCheck() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).addressValidityCheck();
+ ((DirectBuffer) byteBuffer).addressValidityCheck();
} else {
assert false : byteBuffer;
}
}
-
+
public void free() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).free();
+ ((DirectBuffer) byteBuffer).free();
} else {
assert false : byteBuffer;
- }
+ }
}
- // END android-added
+ @Override
public CharBuffer asReadOnlyBuffer() {
CharToByteBufferAdapter buf = new CharToByteBufferAdapter(byteBuffer
.asReadOnlyBuffer());
@@ -120,6 +108,7 @@
return buf;
}
+ @Override
public CharBuffer compact() {
if (byteBuffer.isReadOnly()) {
throw new ReadOnlyBufferException();
@@ -134,6 +123,7 @@
return this;
}
+ @Override
public CharBuffer duplicate() {
CharToByteBufferAdapter buf = new CharToByteBufferAdapter(byteBuffer
.duplicate());
@@ -143,6 +133,7 @@
return buf;
}
+ @Override
public char get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -150,6 +141,7 @@
return byteBuffer.getChar(position++ << 1);
}
+ @Override
public char get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -157,30 +149,37 @@
return byteBuffer.getChar(index << 1);
}
+ @Override
public boolean isDirect() {
return byteBuffer.isDirect();
}
+ @Override
public boolean isReadOnly() {
return byteBuffer.isReadOnly();
}
+ @Override
public ByteOrder order() {
return byteBuffer.order();
}
+ @Override
protected char[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public CharBuffer put(char c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -189,6 +188,7 @@
return this;
}
+ @Override
public CharBuffer put(int index, char c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -197,6 +197,7 @@
return this;
}
+ @Override
public CharBuffer slice() {
byteBuffer.limit(limit << 1);
byteBuffer.position(position << 1);
@@ -205,11 +206,12 @@
return result;
}
+ @Override
public CharSequence subSequence(int start, int end) {
if (start < 0 || end < start || end > remaining()) {
throw new IndexOutOfBoundsException();
}
-
+
CharBuffer result = duplicate();
result.limit(position + end);
result.position(position + start);
diff --git a/nio/src/main/java/java/nio/DirectByteBuffer.java b/nio/src/main/java/java/nio/DirectByteBuffer.java
index dcdb3c1..9bf6813 100644
--- a/nio/src/main/java/java/nio/DirectByteBuffer.java
+++ b/nio/src/main/java/java/nio/DirectByteBuffer.java
@@ -22,7 +22,6 @@
import org.apache.harmony.nio.internal.DirectBuffer;
import org.apache.harmony.nio.internal.nls.Messages;
-
/**
* DirectByteBuffer, ReadWriteDirectByteBuffer and ReadOnlyDirectByteBuffer
* compose the implementation of platform memory based byte buffers.
@@ -58,13 +57,14 @@
/*
* Constructs a new direct byte buffer of the given capacity on newly
- * allocated OS memory. The memory will have been zeroed. When the
- * instance is discarded the OS memory will be freed if it has not
- * already been done so by an explicit call to #free(). Callers are
- * encouraged to explicitly free the memory where possible.
+ * allocated OS memory. The memory will have been zeroed. When the instance
+ * is discarded the OS memory will be freed if it has not already been done
+ * so by an explicit call to #free(). Callers are encouraged to explicitly
+ * free the memory where possible.
*/
DirectByteBuffer(int capacity) {
- this(new SafeAddress(PlatformAddressFactory.alloc(capacity, (byte)0)), capacity, 0);
+ this(new SafeAddress(PlatformAddressFactory.alloc(capacity, (byte) 0)),
+ capacity, 0);
safeAddress.address.autoFree();
}
@@ -79,7 +79,7 @@
throw new IllegalArgumentException("slice out of range");
}
// END android-added
-
+
this.safeAddress = address;
this.offset = offset;
}
@@ -88,21 +88,24 @@
* Override ByteBuffer.get(byte[], int, int) to improve performance.
*
* (non-Javadoc)
+ *
* @see java.nio.ByteBuffer#get(byte[], int, int)
*/
+ @Override
public final ByteBuffer get(byte[] dest, int off, int len) {
int length = dest.length;
- if ((off < 0 ) || (len < 0) || (long)off + (long)len > length) {
+ if ((off < 0) || (len < 0) || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferUnderflowException();
}
- getBaseAddress().getByteArray(offset+position, dest, off, len);
+ getBaseAddress().getByteArray(offset + position, dest, off, len);
position += len;
return this;
}
-
+
+ @Override
public final byte get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -110,6 +113,7 @@
return getBaseAddress().getByte(offset + position++);
}
+ @Override
public final byte get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -117,6 +121,7 @@
return getBaseAddress().getByte(offset + index);
}
+ @Override
public final double getDouble() {
int newPosition = position + 8;
if (newPosition > limit) {
@@ -127,13 +132,15 @@
return result;
}
+ @Override
public final double getDouble(int index) {
- if (index < 0 || (long)index + 8 > limit) {
+ if (index < 0 || (long) index + 8 > limit) {
throw new IndexOutOfBoundsException();
}
return getBaseAddress().getDouble(offset + index, order);
}
+ @Override
public final float getFloat() {
int newPosition = position + 4;
if (newPosition > limit) {
@@ -144,13 +151,15 @@
return result;
}
+ @Override
public final float getFloat(int index) {
- if (index < 0 || (long)index + 4 > limit) {
+ if (index < 0 || (long) index + 4 > limit) {
throw new IndexOutOfBoundsException();
}
return getBaseAddress().getFloat(offset + index, order);
}
+ @Override
public final int getInt() {
int newPosition = position + 4;
if (newPosition > limit) {
@@ -161,13 +170,15 @@
return result;
}
+ @Override
public final int getInt(int index) {
- if (index < 0 || (long)index + 4 > limit) {
+ if (index < 0 || (long) index + 4 > limit) {
throw new IndexOutOfBoundsException();
}
return getBaseAddress().getInt(offset + index, order);
}
+ @Override
public final long getLong() {
int newPosition = position + 8;
if (newPosition > limit) {
@@ -178,13 +189,15 @@
return result;
}
+ @Override
public final long getLong(int index) {
- if (index < 0 || (long)index + 8 > limit) {
+ if (index < 0 || (long) index + 8 > limit) {
throw new IndexOutOfBoundsException();
}
return getBaseAddress().getLong(offset + index, order);
}
+ @Override
public final short getShort() {
int newPosition = position + 2;
if (newPosition > limit) {
@@ -195,13 +208,15 @@
return result;
}
+ @Override
public final short getShort(int index) {
- if (index < 0 || (long)index + 2 > limit) {
+ if (index < 0 || (long) index + 2 > limit) {
throw new IndexOutOfBoundsException();
}
return getBaseAddress().getShort(offset + index, order);
}
+ @Override
public final boolean isDirect() {
return true;
}
@@ -212,9 +227,9 @@
public final void addressValidityCheck() {
if (!isAddressValid()) {
- // nio.08=Cannot use the direct byte buffer after it has been explicitly freed.
- throw new IllegalStateException(
- Messages.getString("nio.08")); //$NON-NLS-1$
+ // nio.08=Cannot use the direct byte buffer after it has been
+ // explicitly freed.
+ throw new IllegalStateException(Messages.getString("nio.08")); //$NON-NLS-1$
}
}
@@ -271,23 +286,23 @@
safeAddress.address.free();
}
}
-
+
+ @Override
final protected byte[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
final protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
final protected boolean protectedHasArray() {
return false;
}
- // BEGIN android-added
- // copied from newer version of harmony
public final int getByteCapacity() {
return capacity;
}
- // END android-added
}
diff --git a/nio/src/main/java/java/nio/DirectByteBuffers.java b/nio/src/main/java/java/nio/DirectByteBuffers.java
index 03a0df7..77b6ebd 100644
--- a/nio/src/main/java/java/nio/DirectByteBuffers.java
+++ b/nio/src/main/java/java/nio/DirectByteBuffers.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package java.nio;
+package java.nio;
import org.apache.harmony.luni.platform.PlatformAddress;
@@ -31,13 +31,11 @@
* If the memory is known to already have been freed then this is a no-op.
* Once the memory has been freed then operations requiring access to the
* memory will throw an <code>IllegalStateException</code>.
- * </p>
* <p>
* Note this is is possible that the memory is freed by code that reaches
* into the address and explicitly frees it 'beneith' us -- this is bad
* form.
- * </p>
- *
+ *
* @param directBuffer
* the direct byte buffer memory to free
* @throws IllegalArgumentException
@@ -61,8 +59,7 @@
* If you can guarantee that you want to free the underlying memory call the
* #free() method on this instance -- generally applications will rely on
* the garbage collector to autofree this memory.
- * </p>
- *
+ *
* @param directBuffer
* the direct byte buffer
* @return the effective address of the start of the buffer.
diff --git a/nio/src/main/java/java/nio/DoubleArrayBuffer.java b/nio/src/main/java/java/nio/DoubleArrayBuffer.java
index ad488ea..ce1e3a6 100644
--- a/nio/src/main/java/java/nio/DoubleArrayBuffer.java
+++ b/nio/src/main/java/java/nio/DoubleArrayBuffer.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package java.nio;
+package java.nio;
/**
* DoubleArrayBuffer, ReadWriteDoubleArrayBuffer and ReadOnlyDoubleArrayBuffer
@@ -49,6 +49,7 @@
this.offset = offset;
}
+ @Override
public final double get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -56,6 +57,7 @@
return backingArray[offset + position++];
}
+ @Override
public final double get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -63,24 +65,26 @@
return backingArray[offset + index];
}
+ @Override
public final DoubleBuffer get(double[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferUnderflowException();
}
- System.arraycopy(backingArray, offset + position, dest,
- off, len);
+ System.arraycopy(backingArray, offset + position, dest, off, len);
position += len;
return this;
}
-
+
+ @Override
public final boolean isDirect() {
return false;
}
+ @Override
public final ByteOrder order() {
return ByteOrder.nativeOrder();
}
diff --git a/nio/src/main/java/java/nio/DoubleBuffer.java b/nio/src/main/java/java/nio/DoubleBuffer.java
index b3c261d..4e0ab01 100644
--- a/nio/src/main/java/java/nio/DoubleBuffer.java
+++ b/nio/src/main/java/java/nio/DoubleBuffer.java
@@ -21,7 +21,6 @@
* A buffer of doubles.
* <p>
* A double buffer can be created in either one of the following ways:
- * </p>
* <ul>
* <li>{@link #allocate(int) Allocate} a new double array and create a buffer
* based on it;</li>
@@ -31,10 +30,9 @@
* {@link java.nio.ByteBuffer#asDoubleBuffer() ByteBuffer.asDoubleBuffer} to
* create a double buffer based on a byte buffer.</li>
* </ul>
- *
- * @since Android 1.0
*/
-public abstract class DoubleBuffer extends Buffer implements Comparable<DoubleBuffer> {
+public abstract class DoubleBuffer extends Buffer implements
+ Comparable<DoubleBuffer> {
/**
* Creates a double buffer based on a newly allocated double array.
@@ -44,7 +42,6 @@
* @return the created double buffer.
* @throws IllegalArgumentException
* if {@code capacity} is less than zero.
- * @since Android 1.0
*/
public static DoubleBuffer allocate(int capacity) {
if (capacity < 0) {
@@ -58,12 +55,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(array, 0, array.length)}.
- * </p>
- *
+ *
* @param array
* the double array which the new buffer will be based on.
* @return the created double buffer.
- * @since Android 1.0
*/
public static DoubleBuffer wrap(double[] array) {
return wrap(array, 0, array.length);
@@ -74,8 +69,7 @@
* <p>
* The new buffer's position will be {@code start}, limit will be
* {@code start + len}, capacity will be the length of the array.
- * </p>
- *
+ *
* @param array
* the double array which the new buffer will be based on.
* @param start
@@ -87,11 +81,10 @@
* @return the created double buffer.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code len} is invalid.
- * @since Android 1.0
*/
public static DoubleBuffer wrap(double[] array, int start, int len) {
int length = array.length;
- if (start < 0 || len < 0 || (long)start + (long)len > length) {
+ if (start < 0 || len < 0 || (long) start + (long) len > length) {
throw new IndexOutOfBoundsException();
}
@@ -123,7 +116,6 @@
* if this buffer is based on an array but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final double[] array() {
return protectedArray();
@@ -135,21 +127,19 @@
* <p>
* The offset is the index of the array corresponding to the zero position
* of the buffer.
- * </p>
- *
+ *
* @return the offset of the double array which this buffer is based on.
* @exception ReadOnlyBufferException
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int arrayOffset() {
return protectedArrayOffset();
}
// BEGIN android-added
- @Override
+ @Override
Object _array() {
if (hasArray()) {
return array();
@@ -157,7 +147,7 @@
return null;
}
- @Override
+ @Override
int _arrayOffset() {
if (hasArray()) {
return arrayOffset();
@@ -172,15 +162,12 @@
* The returned buffer is guaranteed to be a new instance, even if this
* buffer is read-only itself. The new buffer's position, limit, capacity
* and mark are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means that this
* buffer's change of content will be visible to the new buffer. The two
* buffer's position, limit and mark are independent.
- * </p>
- *
+ *
* @return a read-only version of this buffer.
- * @since Android 1.0
*/
public abstract DoubleBuffer asReadOnlyBuffer();
@@ -190,12 +177,10 @@
* The remaining doubles will be moved to the head of the buffer, staring
* from position zero. Then the position is set to {@code remaining()}; the
* limit is set to capacity; the mark is cleared.
- * </p>
- *
+ *
* @return this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract DoubleBuffer compact();
@@ -210,14 +195,12 @@
* than {@code other}.
* @exception ClassCastException
* if {@code other} is not a double buffer.
- * @since Android 1.0
*/
public int compareTo(DoubleBuffer otherBuffer) {
int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
: otherBuffer.remaining();
int thisPos = position;
int otherPos = otherBuffer.position;
- // BEGIN android-changed
double thisDouble, otherDouble;
while (compareRemaining > 0) {
thisDouble = get(thisPos);
@@ -231,7 +214,6 @@
otherPos++;
compareRemaining--;
}
- // END android-changed
return remaining() - otherBuffer.remaining();
}
@@ -241,15 +223,12 @@
* The duplicated buffer's position, limit, capacity and mark are the same
* as this buffer's. The duplicated buffer's read-only property and byte
* order are the same as this buffer's, too.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a duplicated buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract DoubleBuffer duplicate();
@@ -259,14 +238,13 @@
* If {@code other} is not a double buffer then {@code false} is returned.
* Two double buffers are equal if and only if their remaining doubles are
* exactly the same. Position, limit, capacity and mark are not considered.
- * </p>
- *
+ *
* @param other
* the object to compare with this double buffer.
* @return {@code true} if this double buffer is equal to {@code other},
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof DoubleBuffer)) {
return false;
@@ -294,7 +272,6 @@
* @return the double at the current position.
* @exception BufferUnderflowException
* if the position is equal or greater than limit.
- * @since Android 1.0
*/
public abstract double get();
@@ -304,14 +281,12 @@
* <p>
* Calling this method has the same effect as
* {@code get(dest, 0, dest.length)}.
- * </p>
- *
+ *
* @param dest
* the destination double array.
* @return this buffer.
* @exception BufferUnderflowException
* if {@code dest.length} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public DoubleBuffer get(double[] dest) {
return get(dest, 0, dest.length);
@@ -335,14 +310,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception BufferUnderflowException
* if {@code len} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public DoubleBuffer get(double[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferUnderflowException();
}
@@ -360,17 +334,15 @@
* @return a double at the specified index.
* @exception IndexOutOfBoundsException
* if index is invalid.
- * @since Android 1.0
*/
public abstract double get(int index);
/**
* Indicates whether this buffer is based on a double array and is
* read/write.
- *
+ *
* @return {@code true} if this buffer is based on a double array and
* provides read/write access, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasArray() {
return protectedHasArray();
@@ -379,10 +351,10 @@
/**
* Calculates this buffer's hash code from the remaining chars. The
* position, limit, capacity and mark don't affect the hash code.
- *
+ *
* @return the hash code calculated from the remaining chars.
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int myPosition = position;
int hash = 0;
@@ -401,10 +373,8 @@
* <p>
* A double buffer is direct if it is based on a byte buffer and the byte
* buffer is direct.
- * </p>
*
* @return {@code true} if this buffer is direct, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isDirect();
@@ -414,11 +384,9 @@
* <p>
* If this buffer is not based on a byte buffer, then this always returns
* the platform's native byte order.
- * </p>
- *
+ *
* @return the byte order used by this buffer when converting doubles
* from/to bytes.
- * @since Android 1.0
*/
public abstract ByteOrder order();
@@ -454,7 +422,6 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract DoubleBuffer put(double d);
@@ -464,8 +431,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(src, 0, src.length)}.
- * </p>
- *
+ *
* @param src
* the source double array.
* @return this buffer.
@@ -473,7 +439,6 @@
* if {@code remaining()} is less than {@code src.length}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final DoubleBuffer put(double[] src) {
return put(src, 0, src.length);
@@ -499,14 +464,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public DoubleBuffer put(double[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferOverflowException();
}
@@ -531,7 +495,6 @@
* if {@code src} is this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public DoubleBuffer put(DoubleBuffer src) {
if (src == this) {
@@ -559,7 +522,6 @@
* if index is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract DoubleBuffer put(int index, double d);
@@ -571,15 +533,12 @@
* The new buffer's position will be 0, limit will be its capacity, and its
* mark is cleared. The new buffer's read-only property and byte order are
* the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a sliced buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract DoubleBuffer slice();
@@ -587,16 +546,16 @@
* Returns a string representing the state of this double buffer.
*
* @return A string representing the state of this double buffer.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append(getClass().getName());
buf.append(", status: capacity="); //$NON-NLS-1$
buf.append(capacity());
buf.append(" position="); //$NON-NLS-1$
buf.append(position());
- buf.append(" limit="); //$NON-NLS-1$
+ buf.append(" limit="); //$NON-NLS-1$
buf.append(limit());
return buf.toString();
}
diff --git a/nio/src/main/java/java/nio/DoubleToByteBufferAdapter.java b/nio/src/main/java/java/nio/DoubleToByteBufferAdapter.java
index 70406ba..da53bdc 100644
--- a/nio/src/main/java/java/nio/DoubleToByteBufferAdapter.java
+++ b/nio/src/main/java/java/nio/DoubleToByteBufferAdapter.java
@@ -16,11 +16,8 @@
package java.nio;
-// BEGIN android-added
-// Copied from newer version of harmony
import org.apache.harmony.nio.internal.DirectBuffer;
import org.apache.harmony.luni.platform.PlatformAddress;
-// END android-added
/**
* This class wraps a byte buffer to be a double buffer.
@@ -35,10 +32,8 @@
* </p>
*
*/
-// BEGIN android-changed
-// Copied from newer version of harmony
-final class DoubleToByteBufferAdapter extends DoubleBuffer implements DirectBuffer {
-// END android-changed
+final class DoubleToByteBufferAdapter extends DoubleBuffer implements
+ DirectBuffer {
static DoubleBuffer wrap(ByteBuffer byteBuffer) {
return new DoubleToByteBufferAdapter(byteBuffer.slice());
@@ -52,15 +47,12 @@
this.byteBuffer.clear();
}
- // BEGIN android-added
- // Copied from newer version of harmony
public int getByteCapacity() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getByteCapacity();
- } else {
- assert false : byteBuffer;
- return -1;
- }
+ return ((DirectBuffer) byteBuffer).getByteCapacity();
+ }
+ assert false : byteBuffer;
+ return -1;
}
public PlatformAddress getEffectiveAddress() {
@@ -70,47 +62,44 @@
effectiveDirectAddress = addr.toInt();
return addr;
// END android-changed
- } else {
- assert false : byteBuffer;
- return null;
}
+ assert false : byteBuffer;
+ return null;
}
public PlatformAddress getBaseAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getBaseAddress();
- } else {
- assert false : byteBuffer;
- return null;
+ return ((DirectBuffer) byteBuffer).getBaseAddress();
}
+ assert false : byteBuffer;
+ return null;
}
-
+
public boolean isAddressValid() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).isAddressValid();
- } else {
- assert false : byteBuffer;
- return false;
+ return ((DirectBuffer) byteBuffer).isAddressValid();
}
+ assert false : byteBuffer;
+ return false;
}
public void addressValidityCheck() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).addressValidityCheck();
+ ((DirectBuffer) byteBuffer).addressValidityCheck();
} else {
assert false : byteBuffer;
}
}
-
+
public void free() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).free();
+ ((DirectBuffer) byteBuffer).free();
} else {
assert false : byteBuffer;
- }
+ }
}
- // END android-added
-
+
+ @Override
public DoubleBuffer asReadOnlyBuffer() {
DoubleToByteBufferAdapter buf = new DoubleToByteBufferAdapter(
byteBuffer.asReadOnlyBuffer());
@@ -120,6 +109,7 @@
return buf;
}
+ @Override
public DoubleBuffer compact() {
if (byteBuffer.isReadOnly()) {
throw new ReadOnlyBufferException();
@@ -134,6 +124,7 @@
return this;
}
+ @Override
public DoubleBuffer duplicate() {
DoubleToByteBufferAdapter buf = new DoubleToByteBufferAdapter(
byteBuffer.duplicate());
@@ -143,6 +134,7 @@
return buf;
}
+ @Override
public double get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -150,6 +142,7 @@
return byteBuffer.getDouble(position++ << 3);
}
+ @Override
public double get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -157,30 +150,37 @@
return byteBuffer.getDouble(index << 3);
}
+ @Override
public boolean isDirect() {
return byteBuffer.isDirect();
}
+ @Override
public boolean isReadOnly() {
return byteBuffer.isReadOnly();
}
+ @Override
public ByteOrder order() {
return byteBuffer.order();
}
+ @Override
protected double[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public DoubleBuffer put(double c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -189,6 +189,7 @@
return this;
}
+ @Override
public DoubleBuffer put(int index, double c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -197,6 +198,7 @@
return this;
}
+ @Override
public DoubleBuffer slice() {
byteBuffer.limit(limit << 3);
byteBuffer.position(position << 3);
diff --git a/nio/src/main/java/java/nio/FloatArrayBuffer.java b/nio/src/main/java/java/nio/FloatArrayBuffer.java
index bb07e97..0dcc89c 100644
--- a/nio/src/main/java/java/nio/FloatArrayBuffer.java
+++ b/nio/src/main/java/java/nio/FloatArrayBuffer.java
@@ -49,6 +49,7 @@
this.offset = offset;
}
+ @Override
public final float get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -56,6 +57,7 @@
return backingArray[offset + position++];
}
+ @Override
public final float get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -63,23 +65,26 @@
return backingArray[offset + index];
}
+ @Override
public final FloatBuffer get(float[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferUnderflowException();
}
- System.arraycopy(backingArray, offset+position, dest, off, len);
+ System.arraycopy(backingArray, offset + position, dest, off, len);
position += len;
return this;
}
-
+
+ @Override
public final boolean isDirect() {
return false;
}
+ @Override
public final ByteOrder order() {
return ByteOrder.nativeOrder();
}
diff --git a/nio/src/main/java/java/nio/FloatBuffer.java b/nio/src/main/java/java/nio/FloatBuffer.java
index f7ee917..cab94c3 100644
--- a/nio/src/main/java/java/nio/FloatBuffer.java
+++ b/nio/src/main/java/java/nio/FloatBuffer.java
@@ -21,7 +21,6 @@
* A buffer of floats.
* <p>
* A float buffer can be created in either of the following ways:
- * </p>
* <ul>
* <li>{@link #allocate(int) Allocate} a new float array and create a buffer
* based on it;</li>
@@ -30,10 +29,9 @@
* <li>Use {@link java.nio.ByteBuffer#asFloatBuffer() ByteBuffer.asFloatBuffer}
* to create a float buffer based on a byte buffer.</li>
* </ul>
- *
- * @since Android 1.0
*/
-public abstract class FloatBuffer extends Buffer implements Comparable<FloatBuffer> {
+public abstract class FloatBuffer extends Buffer implements
+ Comparable<FloatBuffer> {
/**
* Creates a float buffer based on a newly allocated float array.
@@ -43,7 +41,6 @@
* @return the created float buffer.
* @throws IllegalArgumentException
* if {@code capacity} is less than zero.
- * @since Android 1.0
*/
public static FloatBuffer allocate(int capacity) {
if (capacity < 0) {
@@ -57,12 +54,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(array, 0, array.length)}.
- * </p>
- *
+ *
* @param array
* the float array which the new buffer will be based on.
* @return the created float buffer.
- * @since Android 1.0
*/
public static FloatBuffer wrap(float[] array) {
return wrap(array, 0, array.length);
@@ -73,8 +68,7 @@
* <p>
* The new buffer's position will be {@code start}, limit will be
* {@code start + len}, capacity will be the length of the array.
- * </p>
- *
+ *
* @param array
* the float array which the new buffer will be based on.
* @param start
@@ -88,15 +82,14 @@
* if either {@code start} or {@code len} is invalid.
* @exception NullPointerException
* if {@code array} is null.
- * @since Android 1.0
*/
public static FloatBuffer wrap(float[] array, int start, int len) {
- if (array == null) {
- throw new NullPointerException();
- }
- if (start < 0 || len < 0 || (long)start + (long)len > array.length) {
- throw new IndexOutOfBoundsException();
- }
+ if (array == null) {
+ throw new NullPointerException();
+ }
+ if (start < 0 || len < 0 || (long) start + (long) len > array.length) {
+ throw new IndexOutOfBoundsException();
+ }
FloatBuffer buf = BufferFactory.newFloatBuffer(array);
buf.position = start;
@@ -125,7 +118,6 @@
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final float[] array() {
return protectedArray();
@@ -137,14 +129,12 @@
* <p>
* The offset is the index of the array and corresponds to the zero position
* of the buffer.
- * </p>
- *
+ *
* @return the offset of the float array which this buffer is based on.
* @exception ReadOnlyBufferException
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int arrayOffset() {
return protectedArrayOffset();
@@ -172,15 +162,12 @@
* The returned buffer is guaranteed to be a new instance, even if this
* buffer is read-only itself. The new buffer's position, limit, capacity
* and mark are the same as this buffer.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means this
* buffer's change of content will be visible to the new buffer. The two
* buffer's position, limit and mark are independent.
- * </p>
- *
+ *
* @return a read-only version of this buffer.
- * @since Android 1.0
*/
public abstract FloatBuffer asReadOnlyBuffer();
@@ -190,12 +177,10 @@
* The remaining floats will be moved to the head of the buffer, starting
* from position zero. Then the position is set to {@code remaining()}; the
* limit is set to capacity; the mark is cleared.
- * </p>
- *
+ *
* @return this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract FloatBuffer compact();
@@ -210,14 +195,12 @@
* greater than {@code otherBuffer}.
* @exception ClassCastException
* if {@code otherBuffer} is not a float buffer.
- * @since Android 1.0
*/
public int compareTo(FloatBuffer otherBuffer) {
int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
: otherBuffer.remaining();
int thisPos = position;
int otherPos = otherBuffer.position;
- // BEGIN android-changed
float thisFloat, otherFloat;
while (compareRemaining > 0) {
thisFloat = get(thisPos);
@@ -231,7 +214,6 @@
otherPos++;
compareRemaining--;
}
- // END android-changed
return remaining() - otherBuffer.remaining();
}
@@ -241,15 +223,12 @@
* The duplicated buffer's position, limit, capacity and mark are the same
* as this buffer. The duplicated buffer's read-only property and byte order
* are same as this buffer too.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a duplicated buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract FloatBuffer duplicate();
@@ -259,14 +238,13 @@
* If {@code other} is not a float buffer then {@code false} is returned.
* Two float buffers are equal if and only if their remaining floats are
* exactly the same. Position, limit, capacity and mark are not considered.
- * </p>
- *
+ *
* @param other
* the object to compare with this float buffer.
* @return {@code true} if this float buffer is equal to {@code other},
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof FloatBuffer)) {
return false;
@@ -294,7 +272,6 @@
* @return the float at the current position.
* @exception BufferUnderflowException
* if the position is equal or greater than limit.
- * @since Android 1.0
*/
public abstract float get();
@@ -304,14 +281,12 @@
* <p>
* Calling this method has the same effect as
* {@code get(dest, 0, dest.length)}.
- * </p>
- *
+ *
* @param dest
* the destination float array.
* @return this buffer.
* @exception BufferUnderflowException
* if {@code dest.length} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public FloatBuffer get(float[] dest) {
return get(dest, 0, dest.length);
@@ -335,14 +310,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception BufferUnderflowException
* if {@code len} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public FloatBuffer get(float[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferUnderflowException();
}
@@ -360,17 +334,15 @@
* @return a float at the specified index.
* @exception IndexOutOfBoundsException
* if index is invalid.
- * @since Android 1.0
*/
public abstract float get(int index);
/**
* Indicates whether this buffer is based on a float array and is
* read/write.
- *
+ *
* @return {@code true} if this buffer is based on a float array and
* provides read/write access, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasArray() {
return protectedHasArray();
@@ -379,10 +351,10 @@
/**
* Calculates this buffer's hash code from the remaining chars. The
* position, limit, capacity and mark don't affect the hash code.
- *
+ *
* @return the hash code calculated from the remaining floats.
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int myPosition = position;
int hash = 0;
@@ -399,10 +371,8 @@
* <p>
* A float buffer is direct if it is based on a byte buffer and the byte
* buffer is direct.
- * </p>
- *
+ *
* @return {@code true} if this buffer is direct, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isDirect();
@@ -412,11 +382,9 @@
* <p>
* If this buffer is not based on a byte buffer, then always return the
* platform's native byte order.
- * </p>
- *
+ *
* @return the byte order used by this buffer when converting floats from/to
* bytes.
- * @since Android 1.0
*/
public abstract ByteOrder order();
@@ -452,7 +420,6 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract FloatBuffer put(float f);
@@ -462,8 +429,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(src, 0, src.length)}.
- * </p>
- *
+ *
* @param src
* the source float array.
* @return this buffer.
@@ -471,7 +437,6 @@
* if {@code remaining()} is less than {@code src.length}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final FloatBuffer put(float[] src) {
return put(src, 0, src.length);
@@ -497,14 +462,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public FloatBuffer put(float[] src, int off, int len) {
int length = src.length;
if (off < 0 || len < 0 || (long)off + (long)len > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferOverflowException();
}
@@ -529,7 +493,6 @@
* if {@code src} is this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public FloatBuffer put(FloatBuffer src) {
if (src == this) {
@@ -557,7 +520,6 @@
* if index is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract FloatBuffer put(int index, float f);
@@ -569,15 +531,12 @@
* The new buffer's position will be 0, limit will be its capacity, and its
* mark is cleared. The new buffer's read-only property and byte order are
* same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
*
* @return a sliced buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract FloatBuffer slice();
@@ -585,10 +544,10 @@
* Returns a string representing the state of this float buffer.
*
* @return a string representing the state of this float buffer.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append(getClass().getName());
buf.append(", status: capacity="); //$NON-NLS-1$
buf.append(capacity());
diff --git a/nio/src/main/java/java/nio/FloatToByteBufferAdapter.java b/nio/src/main/java/java/nio/FloatToByteBufferAdapter.java
index 75b9d84..d91ad0d 100644
--- a/nio/src/main/java/java/nio/FloatToByteBufferAdapter.java
+++ b/nio/src/main/java/java/nio/FloatToByteBufferAdapter.java
@@ -16,11 +16,8 @@
package java.nio;
-// BEGIN android-added
-// copied from newer version of harmony
import org.apache.harmony.nio.internal.DirectBuffer;
import org.apache.harmony.luni.platform.PlatformAddress;
-// END android-added
/**
* This class wraps a byte buffer to be a float buffer.
@@ -35,10 +32,8 @@
* </p>
*
*/
-// BEGIN android-changed
-// copied from newer version of harmony
-final class FloatToByteBufferAdapter extends FloatBuffer implements DirectBuffer {
-// END android-changed
+final class FloatToByteBufferAdapter extends FloatBuffer implements
+ DirectBuffer {
static FloatBuffer wrap(ByteBuffer byteBuffer) {
return new FloatToByteBufferAdapter(byteBuffer.slice());
@@ -52,15 +47,12 @@
this.byteBuffer.clear();
}
- // BEGIN android-added
- // copied from newer version of harmony
public int getByteCapacity() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getByteCapacity();
- } else {
- assert false : byteBuffer;
- return -1;
- }
+ return ((DirectBuffer) byteBuffer).getByteCapacity();
+ }
+ assert false : byteBuffer;
+ return -1;
}
public PlatformAddress getEffectiveAddress() {
@@ -70,47 +62,44 @@
effectiveDirectAddress = addr.toInt();
return addr;
// END android-changed
- } else {
- assert false : byteBuffer;
- return null;
}
+ assert false : byteBuffer;
+ return null;
}
public PlatformAddress getBaseAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getBaseAddress();
- } else {
- assert false : byteBuffer;
- return null;
+ return ((DirectBuffer) byteBuffer).getBaseAddress();
}
+ assert false : byteBuffer;
+ return null;
}
-
+
public boolean isAddressValid() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).isAddressValid();
- } else {
- assert false : byteBuffer;
- return false;
+ return ((DirectBuffer) byteBuffer).isAddressValid();
}
+ assert false : byteBuffer;
+ return false;
}
public void addressValidityCheck() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).addressValidityCheck();
+ ((DirectBuffer) byteBuffer).addressValidityCheck();
} else {
assert false : byteBuffer;
}
}
-
+
public void free() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).free();
+ ((DirectBuffer) byteBuffer).free();
} else {
assert false : byteBuffer;
- }
+ }
}
- // END android-added
+ @Override
public FloatBuffer asReadOnlyBuffer() {
FloatToByteBufferAdapter buf = new FloatToByteBufferAdapter(byteBuffer
.asReadOnlyBuffer());
@@ -120,6 +109,7 @@
return buf;
}
+ @Override
public FloatBuffer compact() {
if (byteBuffer.isReadOnly()) {
throw new ReadOnlyBufferException();
@@ -134,6 +124,7 @@
return this;
}
+ @Override
public FloatBuffer duplicate() {
FloatToByteBufferAdapter buf = new FloatToByteBufferAdapter(byteBuffer
.duplicate());
@@ -143,6 +134,7 @@
return buf;
}
+ @Override
public float get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -150,6 +142,7 @@
return byteBuffer.getFloat(position++ << 2);
}
+ @Override
public float get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -157,30 +150,37 @@
return byteBuffer.getFloat(index << 2);
}
+ @Override
public boolean isDirect() {
return byteBuffer.isDirect();
}
+ @Override
public boolean isReadOnly() {
return byteBuffer.isReadOnly();
}
+ @Override
public ByteOrder order() {
return byteBuffer.order();
}
+ @Override
protected float[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public FloatBuffer put(float c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -189,6 +189,7 @@
return this;
}
+ @Override
public FloatBuffer put(int index, float c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -197,6 +198,7 @@
return this;
}
+ @Override
public FloatBuffer slice() {
byteBuffer.limit(limit << 2);
byteBuffer.position(position << 2);
diff --git a/nio/src/main/java/java/nio/HeapByteBuffer.java b/nio/src/main/java/java/nio/HeapByteBuffer.java
index 49c4038..a87d5b3 100644
--- a/nio/src/main/java/java/nio/HeapByteBuffer.java
+++ b/nio/src/main/java/java/nio/HeapByteBuffer.java
@@ -62,9 +62,10 @@
*
* @see java.nio.ByteBuffer#get(byte[], int, int)
*/
+ @Override
public final ByteBuffer get(byte[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
@@ -74,7 +75,8 @@
position += len;
return this;
}
-
+
+ @Override
public final byte get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -82,6 +84,7 @@
return backingArray[offset + position++];
}
+ @Override
public final byte get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -89,22 +92,27 @@
return backingArray[offset + index];
}
+ @Override
public final double getDouble() {
return Double.longBitsToDouble(getLong());
}
+ @Override
public final double getDouble(int index) {
return Double.longBitsToDouble(getLong(index));
}
+ @Override
public final float getFloat() {
return Float.intBitsToFloat(getInt());
}
+ @Override
public final float getFloat(int index) {
return Float.intBitsToFloat(getInt(index));
}
+ @Override
public final int getInt() {
int newPosition = position + 4;
if (newPosition > limit) {
@@ -115,6 +123,7 @@
return result;
}
+ @Override
public final int getInt(int index) {
if (index < 0 || index + 4 > limit) {
throw new IndexOutOfBoundsException();
@@ -122,6 +131,7 @@
return loadInt(index);
}
+ @Override
public final long getLong() {
int newPosition = position + 8;
if (newPosition > limit) {
@@ -132,6 +142,7 @@
return result;
}
+ @Override
public final long getLong(int index) {
if (index < 0 || index + 8 > limit) {
throw new IndexOutOfBoundsException();
@@ -139,6 +150,7 @@
return loadLong(index);
}
+ @Override
public final short getShort() {
int newPosition = position + 2;
if (newPosition > limit) {
@@ -149,6 +161,7 @@
return result;
}
+ @Override
public final short getShort(int index) {
if (index < 0 || index + 2 > limit) {
throw new IndexOutOfBoundsException();
@@ -156,6 +169,7 @@
return loadShort(index);
}
+ @Override
public final boolean isDirect() {
return false;
}
@@ -163,12 +177,12 @@
protected final int loadInt(int index) {
int baseOffset = offset + index;
int bytes = 0;
- if(order == Endianness.BIG_ENDIAN){
+ if (order == Endianness.BIG_ENDIAN) {
for (int i = 0; i < 4; i++) {
bytes = bytes << 8;
bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
- }
- }else{
+ }
+ } else {
for (int i = 3; i >= 0; i--) {
bytes = bytes << 8;
bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
@@ -180,12 +194,12 @@
protected final long loadLong(int index) {
int baseOffset = offset + index;
long bytes = 0;
- if(order == Endianness.BIG_ENDIAN){
+ if (order == Endianness.BIG_ENDIAN) {
for (int i = 0; i < 8; i++) {
bytes = bytes << 8;
bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
- }
- }else{
+ }
+ } else {
for (int i = 7; i >= 0; i--) {
bytes = bytes << 8;
bytes = bytes | (backingArray[baseOffset + i] & 0xFF);
@@ -196,12 +210,12 @@
protected final short loadShort(int index) {
int baseOffset = offset + index;
- short bytes = 0;
- if(order == Endianness.BIG_ENDIAN){
+ short bytes = 0;
+ if (order == Endianness.BIG_ENDIAN) {
bytes = (short) (backingArray[baseOffset] << 8);
- bytes |= (backingArray[baseOffset + 1] & 0xFF);
- }else{
- bytes = (short) (backingArray[baseOffset+1] << 8);
+ bytes |= (backingArray[baseOffset + 1] & 0xFF);
+ } else {
+ bytes = (short) (backingArray[baseOffset + 1] << 8);
bytes |= (backingArray[baseOffset] & 0xFF);
}
return bytes;
@@ -243,7 +257,7 @@
backingArray[baseOffset] = (byte) ((value >> 8) & 0xFF);
backingArray[baseOffset + 1] = (byte) (value & 0xFF);
} else {
- backingArray[baseOffset+1] = (byte) ((value >> 8) & 0xFF);
+ backingArray[baseOffset + 1] = (byte) ((value >> 8) & 0xFF);
backingArray[baseOffset] = (byte) (value & 0xFF);
}
}
diff --git a/nio/src/main/java/java/nio/IntArrayBuffer.java b/nio/src/main/java/java/nio/IntArrayBuffer.java
index d77268e..0352a0f 100644
--- a/nio/src/main/java/java/nio/IntArrayBuffer.java
+++ b/nio/src/main/java/java/nio/IntArrayBuffer.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package java.nio;
+package java.nio;
/**
* IntArrayBuffer, ReadWriteIntArrayBuffer and ReadOnlyIntArrayBuffer compose
@@ -49,6 +49,7 @@
this.offset = offset;
}
+ @Override
public final int get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -56,6 +57,7 @@
return backingArray[offset + position++];
}
+ @Override
public final int get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -63,23 +65,26 @@
return backingArray[offset + index];
}
+ @Override
public final IntBuffer get(int[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)len + (long)off > length) {
+ if (off < 0 || len < 0 || (long) len + (long) off > length) {
throw new IndexOutOfBoundsException();
- }
+ }
if (len > remaining()) {
throw new BufferUnderflowException();
}
- System.arraycopy(backingArray, offset+position, dest, off, len);
+ System.arraycopy(backingArray, offset + position, dest, off, len);
position += len;
return this;
}
-
+
+ @Override
public final boolean isDirect() {
return false;
}
+ @Override
public final ByteOrder order() {
return ByteOrder.nativeOrder();
}
diff --git a/nio/src/main/java/java/nio/IntBuffer.java b/nio/src/main/java/java/nio/IntBuffer.java
index 7a19dfd..d95783b 100644
--- a/nio/src/main/java/java/nio/IntBuffer.java
+++ b/nio/src/main/java/java/nio/IntBuffer.java
@@ -21,7 +21,6 @@
* A buffer of ints.
* <p>
* A int buffer can be created in either of the following ways:
- * </p>
* <ul>
* <li>{@link #allocate(int) Allocate} a new int array and create a buffer
* based on it;</li>
@@ -29,8 +28,6 @@
* <li>Use {@link java.nio.ByteBuffer#asIntBuffer() ByteBuffer.asIntBuffer} to
* create a int buffer based on a byte buffer.</li>
* </ul>
- *
- * @since Android 1.0
*/
public abstract class IntBuffer extends Buffer implements Comparable<IntBuffer> {
@@ -42,7 +39,6 @@
* @return the created int buffer.
* @throws IllegalArgumentException
* if {@code capacity} is less than zero.
- * @since Android 1.0
*/
public static IntBuffer allocate(int capacity) {
if (capacity < 0) {
@@ -56,12 +52,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(array, 0, array.length)}.
- * </p>
- *
+ *
* @param array
* the int array which the new buffer will be based on.
* @return the created int buffer.
- * @since Android 1.0
*/
public static IntBuffer wrap(int[] array) {
return wrap(array, 0, array.length);
@@ -72,8 +66,7 @@
* <p>
* The new buffer's position will be {@code start}, limit will be
* {@code start + len}, capacity will be the length of the array.
- * </p>
- *
+ *
* @param array
* the int array which the new buffer will be based on.
* @param start
@@ -85,15 +78,14 @@
* @return the created int buffer.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code len} is invalid.
- * @since Android 1.0
*/
public static IntBuffer wrap(int[] array, int start, int len) {
- if (array == null) {
- throw new NullPointerException();
- }
- if (start < 0 || len < 0 || (long)len + (long)start > array.length) {
- throw new IndexOutOfBoundsException();
- }
+ if (array == null) {
+ throw new NullPointerException();
+ }
+ if (start < 0 || len < 0 || (long) len + (long) start > array.length) {
+ throw new IndexOutOfBoundsException();
+ }
IntBuffer buf = BufferFactory.newIntBuffer(array);
buf.position = start;
@@ -123,7 +115,6 @@
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int[] array() {
return protectedArray();
@@ -135,14 +126,12 @@
* <p>
* The offset is the index of the array corresponds to the zero position of
* the buffer.
- * </p>
- *
+ *
* @return the offset of the int array which this buffer is based on.
* @exception ReadOnlyBufferException
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int arrayOffset() {
return protectedArrayOffset();
@@ -170,15 +159,12 @@
* The returned buffer is guaranteed to be a new instance, even this buffer
* is read-only itself. The new buffer's position, limit, capacity and mark
* are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means this
* buffer's change of content will be visible to the new buffer. The two
* buffer's position, limit and mark are independent.
- * </p>
- *
+ *
* @return a read-only version of this buffer.
- * @since Android 1.0
*/
public abstract IntBuffer asReadOnlyBuffer();
@@ -188,12 +174,10 @@
* The remaining ints will be moved to the head of the buffer, starting from
* position zero. Then the position is set to {@code remaining()}; the
* limit is set to capacity; the mark is cleared.
- * </p>
- *
+ *
* @return this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract IntBuffer compact();
@@ -208,7 +192,6 @@
* than {@code other}.
* @exception ClassCastException
* if {@code other} is not an int buffer.
- * @since Android 1.0
*/
public int compareTo(IntBuffer otherBuffer) {
int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
@@ -237,15 +220,12 @@
* The duplicated buffer's position, limit, capacity and mark are the same
* as this buffer. The duplicated buffer's read-only property and byte order
* are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a duplicated buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract IntBuffer duplicate();
@@ -255,14 +235,13 @@
* If {@code other} is not a int buffer then {@code false} is returned. Two
* int buffers are equal if and only if their remaining ints are exactly the
* same. Position, limit, capacity and mark are not considered.
- * </p>
- *
+ *
* @param other
* the object to compare with this int buffer.
* @return {@code true} if this int buffer is equal to {@code other},
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof IntBuffer)) {
return false;
@@ -289,7 +268,6 @@
* @return the int at the current position.
* @exception BufferUnderflowException
* if the position is equal or greater than limit.
- * @since Android 1.0
*/
public abstract int get();
@@ -299,14 +277,12 @@
* <p>
* Calling this method has the same effect as
* {@code get(dest, 0, dest.length)}.
- * </p>
- *
+ *
* @param dest
* the destination int array.
* @return this buffer.
* @exception BufferUnderflowException
* if {@code dest.length} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public IntBuffer get(int[] dest) {
return get(dest, 0, dest.length);
@@ -330,11 +306,10 @@
* if either {@code off} or {@code len} is invalid.
* @exception BufferUnderflowException
* if {@code len} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public IntBuffer get(int[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)len + (long)off > length) {
+ if (off < 0 || len < 0 || (long) len + (long) off > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
@@ -354,16 +329,14 @@
* @return an int at the specified index.
* @exception IndexOutOfBoundsException
* if index is invalid.
- * @since Android 1.0
*/
public abstract int get(int index);
/**
* Indicates whether this buffer is based on a int array and is read/write.
- *
+ *
* @return {@code true} if this buffer is based on a int array and provides
* read/write access, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasArray() {
return protectedHasArray();
@@ -372,10 +345,10 @@
/**
* Calculates this buffer's hash code from the remaining chars. The
* position, limit, capacity and mark don't affect the hash code.
- *
+ *
* @return the hash code calculated from the remaining ints.
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int myPosition = position;
int hash = 0;
@@ -392,11 +365,9 @@
* <p>
* An int buffer is direct if it is based on a byte buffer and the byte
* buffer is direct.
- * </p>
- *
+ *
* @return {@code true} if this buffer is direct, {@code false} otherwise.
- * @since Android 1.0
- */
+ */
public abstract boolean isDirect();
/**
@@ -405,11 +376,9 @@
* <p>
* If this buffer is not based on a byte buffer, then always return the
* platform's native byte order.
- * </p>
- *
+ *
* @return the byte order used by this buffer when converting ints from/to
* bytes.
- * @since Android 1.0
*/
public abstract ByteOrder order();
@@ -445,7 +414,6 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract IntBuffer put(int i);
@@ -455,8 +423,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(src, 0, src.length)}.
- * </p>
- *
+ *
* @param src
* the source int array.
* @return this buffer.
@@ -464,7 +431,6 @@
* if {@code remaining()} is less than {@code src.length}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final IntBuffer put(int[] src) {
return put(src, 0, src.length);
@@ -490,14 +456,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public IntBuffer put(int[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)len + (long)off > length) {
+ if (off < 0 || len < 0 || (long) len + (long) off > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferOverflowException();
}
@@ -522,7 +487,6 @@
* if {@code src} is this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public IntBuffer put(IntBuffer src) {
if (src == this) {
@@ -550,7 +514,6 @@
* if index is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract IntBuffer put(int index, int i);
@@ -562,15 +525,12 @@
* The new buffer's position will be 0, limit will be its capacity, and its
* mark is cleared. The new buffer's read-only property and byte order are
* same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
*
* @return a sliced buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract IntBuffer slice();
@@ -578,10 +538,10 @@
* Returns a string represents of the state of this int buffer.
*
* @return a string represents of the state of this int buffer.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append(getClass().getName());
buf.append(", status: capacity="); //$NON-NLS-1$
buf.append(capacity());
diff --git a/nio/src/main/java/java/nio/IntToByteBufferAdapter.java b/nio/src/main/java/java/nio/IntToByteBufferAdapter.java
index e77bec6..0631de4 100644
--- a/nio/src/main/java/java/nio/IntToByteBufferAdapter.java
+++ b/nio/src/main/java/java/nio/IntToByteBufferAdapter.java
@@ -16,11 +16,8 @@
package java.nio;
-// BEGIN android-added
-// copied from newer version of harmony
import org.apache.harmony.nio.internal.DirectBuffer;
import org.apache.harmony.luni.platform.PlatformAddress;
-// END android-added
/**
* This class wraps a byte buffer to be a int buffer.
@@ -35,10 +32,7 @@
* </p>
*
*/
-// BEGIN android-changed
-// copied from newer version of harmony
final class IntToByteBufferAdapter extends IntBuffer implements DirectBuffer {
-// END android-changed
static IntBuffer wrap(ByteBuffer byteBuffer) {
return new IntToByteBufferAdapter(byteBuffer.slice());
@@ -52,15 +46,12 @@
this.byteBuffer.clear();
}
- // BEGIN android-added
- // copied from newer version of harmony
public int getByteCapacity() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getByteCapacity();
- } else {
- assert false : byteBuffer;
- return -1;
- }
+ return ((DirectBuffer) byteBuffer).getByteCapacity();
+ }
+ assert false : byteBuffer;
+ return -1;
}
public PlatformAddress getEffectiveAddress() {
@@ -70,47 +61,44 @@
effectiveDirectAddress = addr.toInt();
return addr;
// END android-changed
- } else {
- assert false : byteBuffer;
- return null;
}
+ assert false : byteBuffer;
+ return null;
}
-
+
public PlatformAddress getBaseAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getBaseAddress();
- } else {
- assert false : byteBuffer;
- return null;
+ return ((DirectBuffer) byteBuffer).getBaseAddress();
}
+ assert false : byteBuffer;
+ return null;
}
-
+
public boolean isAddressValid() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).isAddressValid();
- } else {
- assert false : byteBuffer;
- return false;
+ return ((DirectBuffer) byteBuffer).isAddressValid();
}
+ assert false : byteBuffer;
+ return false;
}
public void addressValidityCheck() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).addressValidityCheck();
+ ((DirectBuffer) byteBuffer).addressValidityCheck();
} else {
assert false : byteBuffer;
}
}
-
+
public void free() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).free();
+ ((DirectBuffer) byteBuffer).free();
} else {
assert false : byteBuffer;
- }
+ }
}
- // END android-added
+ @Override
public IntBuffer asReadOnlyBuffer() {
IntToByteBufferAdapter buf = new IntToByteBufferAdapter(byteBuffer
.asReadOnlyBuffer());
@@ -120,6 +108,7 @@
return buf;
}
+ @Override
public IntBuffer compact() {
if (byteBuffer.isReadOnly()) {
throw new ReadOnlyBufferException();
@@ -134,6 +123,7 @@
return this;
}
+ @Override
public IntBuffer duplicate() {
IntToByteBufferAdapter buf = new IntToByteBufferAdapter(byteBuffer
.duplicate());
@@ -143,6 +133,7 @@
return buf;
}
+ @Override
public int get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -150,6 +141,7 @@
return byteBuffer.getInt(position++ << 2);
}
+ @Override
public int get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -157,30 +149,37 @@
return byteBuffer.getInt(index << 2);
}
+ @Override
public boolean isDirect() {
return byteBuffer.isDirect();
}
+ @Override
public boolean isReadOnly() {
return byteBuffer.isReadOnly();
}
+ @Override
public ByteOrder order() {
return byteBuffer.order();
}
+ @Override
protected int[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public IntBuffer put(int c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -189,6 +188,7 @@
return this;
}
+ @Override
public IntBuffer put(int index, int c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -212,6 +212,7 @@
}
// END android-added
+ @Override
public IntBuffer slice() {
byteBuffer.limit(limit << 2);
byteBuffer.position(position << 2);
diff --git a/nio/src/main/java/java/nio/InvalidMarkException.java b/nio/src/main/java/java/nio/InvalidMarkException.java
index 530d9cf..ff41705 100644
--- a/nio/src/main/java/java/nio/InvalidMarkException.java
+++ b/nio/src/main/java/java/nio/InvalidMarkException.java
@@ -16,12 +16,9 @@
package java.nio;
-
/**
* An {@code InvalidMarkException} is thrown when {@code reset()} is called on a
* buffer, but no mark has been set previously.
- *
- * @since Android 1.0
*/
public class InvalidMarkException extends IllegalStateException {
@@ -29,8 +26,6 @@
/**
* Constructs an {@code InvalidMarkException}.
- *
- * @since Android 1.0
*/
public InvalidMarkException() {
super();
diff --git a/nio/src/main/java/java/nio/LongArrayBuffer.java b/nio/src/main/java/java/nio/LongArrayBuffer.java
index efd259c..46c36e4 100644
--- a/nio/src/main/java/java/nio/LongArrayBuffer.java
+++ b/nio/src/main/java/java/nio/LongArrayBuffer.java
@@ -49,6 +49,7 @@
this.offset = offset;
}
+ @Override
public final long get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -56,6 +57,7 @@
return backingArray[offset + position++];
}
+ @Override
public final long get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -63,23 +65,26 @@
return backingArray[offset + index];
}
+ @Override
public final LongBuffer get(long[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)len + (long)off > length) {
+ if (off < 0 || len < 0 || (long) len + (long) off > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferUnderflowException();
}
- System.arraycopy(backingArray, offset+position, dest, off, len);
+ System.arraycopy(backingArray, offset + position, dest, off, len);
position += len;
return this;
}
-
+
+ @Override
public final boolean isDirect() {
return false;
}
+ @Override
public final ByteOrder order() {
return ByteOrder.nativeOrder();
}
diff --git a/nio/src/main/java/java/nio/LongBuffer.java b/nio/src/main/java/java/nio/LongBuffer.java
index b0bf7ea..eecbf5e 100644
--- a/nio/src/main/java/java/nio/LongBuffer.java
+++ b/nio/src/main/java/java/nio/LongBuffer.java
@@ -21,7 +21,6 @@
* A buffer of longs.
* <p>
* A long buffer can be created in either of the following ways:
- * </p>
* <ul>
* <li>{@link #allocate(int) Allocate} a new long array and create a buffer
* based on it;</li>
@@ -30,10 +29,9 @@
* <li>Use {@link java.nio.ByteBuffer#asLongBuffer() ByteBuffer.asLongBuffer}
* to create a long buffer based on a byte buffer.</li>
* </ul>
- *
- * @since Android 1.0
*/
-public abstract class LongBuffer extends Buffer implements Comparable<LongBuffer> {
+public abstract class LongBuffer extends Buffer implements
+ Comparable<LongBuffer> {
/**
* Creates a long buffer based on a newly allocated long array.
@@ -43,7 +41,6 @@
* @return the created long buffer.
* @throws IllegalArgumentException
* if {@code capacity} is less than zero.
- * @since Android 1.0
*/
public static LongBuffer allocate(int capacity) {
if (capacity < 0) {
@@ -57,12 +54,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(array, 0, array.length)}.
- * </p>
- *
+ *
* @param array
* the long array which the new buffer will be based on.
* @return the created long buffer.
- * @since Android 1.0
*/
public static LongBuffer wrap(long[] array) {
return wrap(array, 0, array.length);
@@ -73,8 +68,7 @@
* <p>
* The new buffer's position will be {@code start}, limit will be
* {@code start + len}, capacity will be the length of the array.
- * </p>
- *
+ *
* @param array
* the long array which the new buffer will be based on.
* @param start
@@ -86,15 +80,14 @@
* @return the created long buffer.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code len} is invalid.
- * @since Android 1.0
*/
public static LongBuffer wrap(long[] array, int start, int len) {
- if (array == null) {
- throw new NullPointerException();
- }
- if (start < 0 || len < 0 || (long)len + (long)start > array.length) {
- throw new IndexOutOfBoundsException();
- }
+ if (array == null) {
+ throw new NullPointerException();
+ }
+ if (start < 0 || len < 0 || (long) len + (long) start > array.length) {
+ throw new IndexOutOfBoundsException();
+ }
LongBuffer buf = BufferFactory.newLongBuffer(array);
buf.position = start;
@@ -124,7 +117,6 @@
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final long[] array() {
return protectedArray();
@@ -136,14 +128,12 @@
* <p>
* The offset is the index of the array and corresponds to the zero position
* of the buffer.
- * </p>
- *
+ *
* @return the offset of the long array which this buffer is based on.
* @exception ReadOnlyBufferException
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int arrayOffset() {
return protectedArrayOffset();
@@ -171,15 +161,12 @@
* The returned buffer is guaranteed to be a new instance, even if this
* buffer is read-only itself. The new buffer's position, limit, capacity
* and mark are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means this
* buffer's change of content will be visible to the new buffer. The two
* buffer's position, limit and mark are independent.
- * </p>
- *
+ *
* @return a read-only version of this buffer.
- * @since Android 1.0
*/
public abstract LongBuffer asReadOnlyBuffer();
@@ -189,12 +176,10 @@
* The remaining longs will be moved to the head of the buffer, staring from
* position zero. Then the position is set to {@code remaining()}; the
* limit is set to capacity; the mark is cleared.
- * </p>
- *
+ *
* @return this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract LongBuffer compact();
@@ -209,7 +194,6 @@
* greater than {@code otherBuffer}
* @exception ClassCastException
* if {@code otherBuffer} is not a long buffer.
- * @since Android 1.0
*/
public int compareTo(LongBuffer otherBuffer) {
int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
@@ -238,15 +222,12 @@
* The duplicated buffer's position, limit, capacity and mark are the same
* as this buffer. The duplicated buffer's read-only property and byte order
* are same as this buffer's, too.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a duplicated buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract LongBuffer duplicate();
@@ -256,14 +237,13 @@
* If {@code other} is not a long buffer then {@code false} is returned. Two
* long buffers are equal if and only if their remaining longs are exactly
* the same. Position, limit, capacity and mark are not considered.
- * </p>
- *
+ *
* @param other
* the object to compare with this long buffer.
* @return {@code true} if this long buffer is equal to {@code other},
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof LongBuffer)) {
return false;
@@ -290,7 +270,6 @@
* @return the long at the current position.
* @exception BufferUnderflowException
* if the position is equal or greater than limit.
- * @since Android 1.0
*/
public abstract long get();
@@ -300,14 +279,12 @@
* <p>
* Calling this method has the same effect as
* {@code get(dest, 0, dest.length)}.
- * </p>
*
* @param dest
* the destination long array.
* @return this buffer.
* @exception BufferUnderflowException
* if {@code dest.length} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public LongBuffer get(long[] dest) {
return get(dest, 0, dest.length);
@@ -331,14 +308,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception BufferUnderflowException
* if {@code len} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public LongBuffer get(long[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)len + (long)off > length) {
+ if (off < 0 || len < 0 || (long) len + (long) off > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferUnderflowException();
}
@@ -356,16 +332,14 @@
* @return the long at the specified index.
* @exception IndexOutOfBoundsException
* if index is invalid.
- * @since Android 1.0
*/
public abstract long get(int index);
/**
* Indicates whether this buffer is based on a long array and is read/write.
- *
+ *
* @return {@code true} if this buffer is based on a long array and provides
* read/write access, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasArray() {
return protectedHasArray();
@@ -374,10 +348,10 @@
/**
* Calculates this buffer's hash code from the remaining chars. The
* position, limit, capacity and mark don't affect the hash code.
- *
+ *
* @return the hash code calculated from the remaining longs.
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int myPosition = position;
int hash = 0;
@@ -396,10 +370,8 @@
* <p>
* A long buffer is direct if it is based on a byte buffer and the byte
* buffer is direct.
- * </p>
- *
+ *
* @return {@code true} if this buffer is direct, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isDirect();
@@ -409,11 +381,9 @@
* <p>
* If this buffer is not based on a byte buffer, then always return the
* platform's native byte order.
- * </p>
- *
+ *
* @return the byte order used by this buffer when converting longs from/to
* bytes.
- * @since Android 1.0
*/
public abstract ByteOrder order();
@@ -449,7 +419,6 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract LongBuffer put(long l);
@@ -459,8 +428,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(src, 0, src.length)}.
- * </p>
- *
+ *
* @param src
* the source long array.
* @return this buffer.
@@ -468,7 +436,6 @@
* if {@code remaining()} is less than {@code src.length}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final LongBuffer put(long[] src) {
return put(src, 0, src.length);
@@ -494,14 +461,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public LongBuffer put(long[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)len + (long)off > length) {
+ if (off < 0 || len < 0 || (long) len + (long) off > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferOverflowException();
}
@@ -526,7 +492,6 @@
* if {@code src} is this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public LongBuffer put(LongBuffer src) {
if (src == this) {
@@ -554,7 +519,6 @@
* if index is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract LongBuffer put(int index, long l);
@@ -566,15 +530,12 @@
* The new buffer's position will be 0, limit will be its capacity, and its
* mark is cleared. The new buffer's read-only property and byte order are
* same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a sliced buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract LongBuffer slice();
@@ -582,10 +543,10 @@
* Returns a string representing the state of this long buffer.
*
* @return a string representing the state of this long buffer.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append(getClass().getName());
buf.append(", status: capacity="); //$NON-NLS-1$
buf.append(capacity());
diff --git a/nio/src/main/java/java/nio/LongToByteBufferAdapter.java b/nio/src/main/java/java/nio/LongToByteBufferAdapter.java
index bcdeb2b..8b07ac5 100644
--- a/nio/src/main/java/java/nio/LongToByteBufferAdapter.java
+++ b/nio/src/main/java/java/nio/LongToByteBufferAdapter.java
@@ -16,11 +16,8 @@
package java.nio;
-// BEGIN android-added
-// copied from newer version of harmony
import org.apache.harmony.nio.internal.DirectBuffer;
import org.apache.harmony.luni.platform.PlatformAddress;
-// END android-added
/**
* This class wraps a byte buffer to be a long buffer.
@@ -33,12 +30,9 @@
* The adapter extends Buffer, thus has its own position and limit.</li>
* </ul>
* </p>
- *
+ *
*/
-// BEGIN android-changed
-// copied from newer version of harmony
final class LongToByteBufferAdapter extends LongBuffer implements DirectBuffer {
-// END android-changed
static LongBuffer wrap(ByteBuffer byteBuffer) {
return new LongToByteBufferAdapter(byteBuffer.slice());
@@ -52,15 +46,12 @@
this.byteBuffer.clear();
}
- // BEGIN android-added
- // copied from newer version of harmony
public int getByteCapacity() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getByteCapacity();
- } else {
- assert false : byteBuffer;
- return -1;
- }
+ return ((DirectBuffer) byteBuffer).getByteCapacity();
+ }
+ assert false : byteBuffer;
+ return -1;
}
public PlatformAddress getEffectiveAddress() {
@@ -70,47 +61,44 @@
effectiveDirectAddress = addr.toInt();
return addr;
// END android-changed
- } else {
- assert false : byteBuffer;
- return null;
}
+ assert false : byteBuffer;
+ return null;
}
public PlatformAddress getBaseAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getBaseAddress();
- } else {
- assert false : byteBuffer;
- return null;
+ return ((DirectBuffer) byteBuffer).getBaseAddress();
}
+ assert false : byteBuffer;
+ return null;
}
-
+
public boolean isAddressValid() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).isAddressValid();
+ return ((DirectBuffer) byteBuffer).isAddressValid();
+ }
+ assert false : byteBuffer;
+ return false;
+ }
+
+ public void addressValidityCheck() {
+ if (byteBuffer instanceof DirectBuffer) {
+ ((DirectBuffer) byteBuffer).addressValidityCheck();
} else {
assert false : byteBuffer;
- return false;
}
}
- public void addressValidityCheck() {
- if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).addressValidityCheck();
- } else {
- assert false : byteBuffer;
- }
- }
-
public void free() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).free();
+ ((DirectBuffer) byteBuffer).free();
} else {
assert false : byteBuffer;
- }
+ }
}
- // END android-added
+ @Override
public LongBuffer asReadOnlyBuffer() {
LongToByteBufferAdapter buf = new LongToByteBufferAdapter(byteBuffer
.asReadOnlyBuffer());
@@ -120,6 +108,7 @@
return buf;
}
+ @Override
public LongBuffer compact() {
if (byteBuffer.isReadOnly()) {
throw new ReadOnlyBufferException();
@@ -134,6 +123,7 @@
return this;
}
+ @Override
public LongBuffer duplicate() {
LongToByteBufferAdapter buf = new LongToByteBufferAdapter(byteBuffer
.duplicate());
@@ -143,6 +133,7 @@
return buf;
}
+ @Override
public long get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -150,6 +141,7 @@
return byteBuffer.getLong(position++ << 3);
}
+ @Override
public long get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -157,30 +149,37 @@
return byteBuffer.getLong(index << 3);
}
+ @Override
public boolean isDirect() {
return byteBuffer.isDirect();
}
+ @Override
public boolean isReadOnly() {
return byteBuffer.isReadOnly();
}
+ @Override
public ByteOrder order() {
return byteBuffer.order();
}
+ @Override
protected long[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public LongBuffer put(long c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -189,6 +188,7 @@
return this;
}
+ @Override
public LongBuffer put(int index, long c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -197,6 +197,7 @@
return this;
}
+ @Override
public LongBuffer slice() {
byteBuffer.limit(limit << 3);
byteBuffer.position(position << 3);
diff --git a/nio/src/main/java/java/nio/MappedByteBuffer.java b/nio/src/main/java/java/nio/MappedByteBuffer.java
index 8f6727d..e995f67 100644
--- a/nio/src/main/java/java/nio/MappedByteBuffer.java
+++ b/nio/src/main/java/java/nio/MappedByteBuffer.java
@@ -21,7 +21,6 @@
import org.apache.harmony.luni.platform.PlatformAddress;
import org.apache.harmony.nio.internal.DirectBuffer;
-
/**
* {@code MappedByteBuffer} is a special kind of direct byte buffer which maps a
* region of file to memory.
@@ -30,15 +29,11 @@
* {@link java.nio.channels.FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long) FileChannel.map}.
* Once created, the mapping between the byte buffer and the file region remains
* valid until the byte buffer is garbage collected.
- * </p>
* <p>
* All or part of a {@code MappedByteBuffer}'s content may change or become
* inaccessible at any time, since the mapped file region can be modified by
* another thread or process at any time. If this happens, the behavior of the
* {@code MappedByteBuffer} is undefined.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class MappedByteBuffer extends ByteBuffer {
@@ -59,15 +54,15 @@
super(capa);
mapMode = mode;
switch (mapMode) {
- case IMemorySystem.MMAP_READ_ONLY:
- wrapped = new ReadOnlyDirectByteBuffer(addr, capa, offset);
- break;
- case IMemorySystem.MMAP_READ_WRITE:
- case IMemorySystem.MMAP_WRITE_COPY:
- wrapped = new ReadWriteDirectByteBuffer(addr, capa, offset);
- break;
- default:
- throw new IllegalArgumentException();
+ case IMemorySystem.MMAP_READ_ONLY:
+ wrapped = new ReadOnlyDirectByteBuffer(addr, capa, offset);
+ break;
+ case IMemorySystem.MMAP_READ_WRITE:
+ case IMemorySystem.MMAP_WRITE_COPY:
+ wrapped = new ReadWriteDirectByteBuffer(addr, capa, offset);
+ break;
+ default:
+ throw new IllegalArgumentException();
}
addr.autoFree();
}
@@ -79,10 +74,10 @@
*
* @return {@code true} if this buffer's content is loaded, {@code false}
* otherwise.
- * @since Android 1.0
*/
public final boolean isLoaded() {
- return ((MappedPlatformAddress)((DirectBuffer) wrapped).getBaseAddress()).mmapIsLoaded();
+ return ((MappedPlatformAddress) ((DirectBuffer) wrapped)
+ .getBaseAddress()).mmapIsLoaded();
}
/**
@@ -90,10 +85,10 @@
* succeed.
*
* @return this buffer.
- * @since Android 1.0
*/
public final MappedByteBuffer load() {
- ((MappedPlatformAddress)((DirectBuffer) wrapped).getBaseAddress()).mmapLoad();
+ ((MappedPlatformAddress) ((DirectBuffer) wrapped).getBaseAddress())
+ .mmapLoad();
return this;
}
@@ -104,11 +99,11 @@
* a remote device.
*
* @return this buffer.
- * @since Android 1.0
*/
public final MappedByteBuffer force() {
if (mapMode == IMemorySystem.MMAP_READ_WRITE) {
- ((MappedPlatformAddress)((DirectBuffer) wrapped).getBaseAddress()).mmapFlush();
+ ((MappedPlatformAddress) ((DirectBuffer) wrapped).getBaseAddress())
+ .mmapFlush();
}
return this;
}
diff --git a/nio/src/main/java/java/nio/MappedByteBufferAdapter.java b/nio/src/main/java/java/nio/MappedByteBufferAdapter.java
index 84866dc..54e009b 100644
--- a/nio/src/main/java/java/nio/MappedByteBufferAdapter.java
+++ b/nio/src/main/java/java/nio/MappedByteBufferAdapter.java
@@ -16,7 +16,6 @@
*/
// BEGIN android-note
-// updated to a newer version of harmony
// added some missing updates on position and limit
// END android-note
@@ -25,8 +24,8 @@
import org.apache.harmony.luni.platform.PlatformAddress;
import org.apache.harmony.nio.internal.DirectBuffer;
-
-final class MappedByteBufferAdapter extends MappedByteBuffer implements DirectBuffer {
+final class MappedByteBufferAdapter extends MappedByteBuffer implements
+ DirectBuffer {
private static final int CHAR_SIZE = 2;
@@ -39,7 +38,7 @@
private static final int FLOAT_SIZE = 4;
private static final int DOUBLE_SIZE = 8;
-
+
public MappedByteBufferAdapter(ByteBuffer buffer) {
super(buffer);
}
@@ -49,26 +48,32 @@
super(addr, capa, offset, mode);
}
+ @Override
public CharBuffer asCharBuffer() {
return this.wrapped.asCharBuffer();
}
+ @Override
public DoubleBuffer asDoubleBuffer() {
return this.wrapped.asDoubleBuffer();
}
+ @Override
public FloatBuffer asFloatBuffer() {
return this.wrapped.asFloatBuffer();
}
+ @Override
public IntBuffer asIntBuffer() {
return this.wrapped.asIntBuffer();
}
+ @Override
public LongBuffer asLongBuffer() {
return this.wrapped.asLongBuffer();
}
+ @Override
public ByteBuffer asReadOnlyBuffer() {
MappedByteBufferAdapter buf = new MappedByteBufferAdapter(this.wrapped
.asReadOnlyBuffer());
@@ -78,10 +83,12 @@
return buf;
}
+ @Override
public ShortBuffer asShortBuffer() {
return this.wrapped.asShortBuffer();
}
+ @Override
public ByteBuffer compact() {
if (this.wrapped.isReadOnly()) {
throw new ReadOnlyBufferException();
@@ -96,6 +103,7 @@
return this;
}
+ @Override
public ByteBuffer duplicate() {
MappedByteBufferAdapter buf = new MappedByteBufferAdapter(this.wrapped
.duplicate());
@@ -105,20 +113,23 @@
return buf;
}
+ @Override
public byte get() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
- byte result = this.wrapped.get();
+ byte result = this.wrapped.get();
this.position++;
return result;
}
+ @Override
public byte get(int index) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
return this.wrapped.get(index);
}
+ @Override
public char getChar() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -127,12 +138,14 @@
return result;
}
+ @Override
public char getChar(int index) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
return this.wrapped.getChar(index);
}
+ @Override
public double getDouble() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -141,6 +154,7 @@
return result;
}
+ @Override
public double getDouble(int index) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -155,6 +169,7 @@
// END android-changed
}
+ @Override
public float getFloat() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -163,12 +178,14 @@
return result;
}
+ @Override
public float getFloat(int index) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
return this.wrapped.getFloat(index);
}
+ @Override
public int getInt() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -177,12 +194,14 @@
return result;
}
+ @Override
public int getInt(int index) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
return this.wrapped.getInt(index);
}
+ @Override
public long getLong() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -191,12 +210,14 @@
return result;
}
+ @Override
public long getLong(int index) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
return this.wrapped.getLong(index);
}
+ @Override
public short getShort() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -205,25 +226,30 @@
return result;
}
+ @Override
public short getShort(int index) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
return this.wrapped.getShort(index);
}
+ @Override
public boolean isDirect() {
return true;
}
+ @Override
public boolean isReadOnly() {
return this.wrapped.isReadOnly();
}
+ @Override
ByteBuffer orderImpl(ByteOrder byteOrder) {
super.orderImpl(byteOrder);
return this.wrapped.order(byteOrder);
}
+ @Override
public ByteBuffer put(byte b) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -232,6 +258,7 @@
return this;
}
+ @Override
public ByteBuffer put(byte[] src, int off, int len) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -240,6 +267,7 @@
return this;
}
+ @Override
public ByteBuffer put(int index, byte b) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -247,6 +275,7 @@
return this;
}
+ @Override
public ByteBuffer putChar(char value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -255,6 +284,7 @@
return this;
}
+ @Override
public ByteBuffer putChar(int index, char value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -262,6 +292,7 @@
return this;
}
+ @Override
public ByteBuffer putDouble(double value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -270,6 +301,7 @@
return this;
}
+ @Override
public ByteBuffer putDouble(int index, double value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -277,6 +309,7 @@
return this;
}
+ @Override
public ByteBuffer putFloat(float value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -285,6 +318,7 @@
return this;
}
+ @Override
public ByteBuffer putFloat(int index, float value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -292,6 +326,7 @@
return this;
}
+ @Override
public ByteBuffer putInt(int index, int value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -299,6 +334,7 @@
return this;
}
+ @Override
public ByteBuffer putInt(int value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -307,6 +343,7 @@
return this;
}
+ @Override
public ByteBuffer putLong(int index, long value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -314,6 +351,7 @@
return this;
}
+ @Override
public ByteBuffer putLong(long value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -322,6 +360,7 @@
return this;
}
+ @Override
public ByteBuffer putShort(int index, short value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -329,6 +368,7 @@
return this;
}
+ @Override
public ByteBuffer putShort(short value) {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -337,6 +377,7 @@
return this;
}
+ @Override
public ByteBuffer slice() {
this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
@@ -346,14 +387,17 @@
return result;
}
+ @Override
byte[] protectedArray() {
return this.wrapped.protectedArray();
}
+ @Override
int protectedArrayOffset() {
return this.wrapped.protectedArrayOffset();
}
+ @Override
boolean protectedHasArray() {
return this.wrapped.protectedHasArray();
}
diff --git a/nio/src/main/java/java/nio/ReadOnlyBufferException.java b/nio/src/main/java/java/nio/ReadOnlyBufferException.java
index 62e2d5f..f860e3c 100644
--- a/nio/src/main/java/java/nio/ReadOnlyBufferException.java
+++ b/nio/src/main/java/java/nio/ReadOnlyBufferException.java
@@ -16,12 +16,9 @@
package java.nio;
-
/**
* A {@code ReadOnlyBufferException} is thrown when some write operation is
* called on a read-only buffer.
- *
- * @since Android 1.0
*/
public class ReadOnlyBufferException extends UnsupportedOperationException {
@@ -29,8 +26,6 @@
/**
* Constructs a {@code ReadOnlyBufferException}.
- *
- * @since Android 1.0
*/
public ReadOnlyBufferException() {
super();
diff --git a/nio/src/main/java/java/nio/ReadOnlyCharArrayBuffer.java b/nio/src/main/java/java/nio/ReadOnlyCharArrayBuffer.java
index 461ea4f..54ef89f 100644
--- a/nio/src/main/java/java/nio/ReadOnlyCharArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyCharArrayBuffer.java
@@ -44,57 +44,71 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public CharBuffer asReadOnlyBuffer() {
return duplicate();
}
+ @Override
public CharBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public CharBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
protected char[] protectedArray() {
throw new ReadOnlyBufferException();
}
+ @Override
protected int protectedArrayOffset() {
throw new ReadOnlyBufferException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public CharBuffer put(char c) {
throw new ReadOnlyBufferException();
}
+ @Override
public CharBuffer put(int index, char c) {
throw new ReadOnlyBufferException();
}
+ @Override
public final CharBuffer put(char[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public final CharBuffer put(CharBuffer src) {
throw new ReadOnlyBufferException();
}
+ @Override
public CharBuffer put(String src, int start, int end) {
- if ((start < 0 ) || (end < 0) || (long)start + (long)end > src.length()) {
+ if ((start < 0) || (end < 0)
+ || (long) start + (long) end > src.length()) {
throw new IndexOutOfBoundsException();
}
throw new ReadOnlyBufferException();
}
+ @Override
public CharBuffer slice() {
return new ReadOnlyCharArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadOnlyDirectByteBuffer.java b/nio/src/main/java/java/nio/ReadOnlyDirectByteBuffer.java
index bc0e1cc..ffa6e41 100644
--- a/nio/src/main/java/java/nio/ReadOnlyDirectByteBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyDirectByteBuffer.java
@@ -52,79 +52,98 @@
int offset) {
super(new SafeAddress(address), capacity, offset);
}
-
+
+ @Override
public ByteBuffer asReadOnlyBuffer() {
return copy(this, mark);
}
+ @Override
public ByteBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
public ByteBuffer put(byte value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer put(int index, byte value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer put(byte[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public ByteBuffer putDouble(double value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putDouble(int index, double value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putFloat(float value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putFloat(int index, float value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putInt(int value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putInt(int index, int value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putLong(int index, long value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putLong(long value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putShort(int index, short value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putShort(short value) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public ByteBuffer put(ByteBuffer buf) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer slice() {
ReadOnlyDirectByteBuffer buf = new ReadOnlyDirectByteBuffer(
safeAddress, remaining(), offset + position);
diff --git a/nio/src/main/java/java/nio/ReadOnlyDoubleArrayBuffer.java b/nio/src/main/java/java/nio/ReadOnlyDoubleArrayBuffer.java
index 4f0b5d2..f71899b 100644
--- a/nio/src/main/java/java/nio/ReadOnlyDoubleArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyDoubleArrayBuffer.java
@@ -46,50 +46,62 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public DoubleBuffer asReadOnlyBuffer() {
return duplicate();
}
+ @Override
public DoubleBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public DoubleBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
protected double[] protectedArray() {
throw new ReadOnlyBufferException();
}
+ @Override
protected int protectedArrayOffset() {
throw new ReadOnlyBufferException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public DoubleBuffer put(double c) {
throw new ReadOnlyBufferException();
}
+ @Override
public DoubleBuffer put(int index, double c) {
throw new ReadOnlyBufferException();
}
+ @Override
public final DoubleBuffer put(double[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public final DoubleBuffer put(DoubleBuffer buf) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public DoubleBuffer slice() {
return new ReadOnlyDoubleArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadOnlyFloatArrayBuffer.java b/nio/src/main/java/java/nio/ReadOnlyFloatArrayBuffer.java
index 7559ffa..e8fb7d8 100644
--- a/nio/src/main/java/java/nio/ReadOnlyFloatArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyFloatArrayBuffer.java
@@ -44,50 +44,62 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public FloatBuffer asReadOnlyBuffer() {
return duplicate();
}
+ @Override
public FloatBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public FloatBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
protected float[] protectedArray() {
throw new ReadOnlyBufferException();
}
+ @Override
protected int protectedArrayOffset() {
throw new ReadOnlyBufferException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public FloatBuffer put(float c) {
throw new ReadOnlyBufferException();
}
+ @Override
public FloatBuffer put(int index, float c) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public FloatBuffer put(FloatBuffer buf) {
throw new ReadOnlyBufferException();
}
+ @Override
public final FloatBuffer put(float[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public FloatBuffer slice() {
return new ReadOnlyFloatArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadOnlyHeapByteBuffer.java b/nio/src/main/java/java/nio/ReadOnlyHeapByteBuffer.java
index 857ecff..fba5e04 100644
--- a/nio/src/main/java/java/nio/ReadOnlyHeapByteBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyHeapByteBuffer.java
@@ -45,90 +45,112 @@
super(backingArray, capacity, arrayOffset);
}
+ @Override
public ByteBuffer asReadOnlyBuffer() {
return copy(this, mark);
}
+ @Override
public ByteBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
protected byte[] protectedArray() {
throw new ReadOnlyBufferException();
}
+ @Override
protected int protectedArrayOffset() {
throw new ReadOnlyBufferException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public ByteBuffer put(byte b) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer put(int index, byte b) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer put(byte[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public ByteBuffer putDouble(double value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putDouble(int index, double value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putFloat(float value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putFloat(int index, float value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putInt(int value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putInt(int index, int value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putLong(int index, long value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putLong(long value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putShort(int index, short value) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer putShort(short value) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public ByteBuffer put(ByteBuffer buf) {
throw new ReadOnlyBufferException();
}
+ @Override
public ByteBuffer slice() {
ReadOnlyHeapByteBuffer slice = new ReadOnlyHeapByteBuffer(backingArray,
remaining(), offset + position);
diff --git a/nio/src/main/java/java/nio/ReadOnlyIntArrayBuffer.java b/nio/src/main/java/java/nio/ReadOnlyIntArrayBuffer.java
index ba9380e..cece133 100644
--- a/nio/src/main/java/java/nio/ReadOnlyIntArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyIntArrayBuffer.java
@@ -44,50 +44,62 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public IntBuffer asReadOnlyBuffer() {
return duplicate();
}
+ @Override
public IntBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public IntBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
protected int[] protectedArray() {
throw new ReadOnlyBufferException();
}
+ @Override
protected int protectedArrayOffset() {
throw new ReadOnlyBufferException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public IntBuffer put(int c) {
throw new ReadOnlyBufferException();
}
+ @Override
public IntBuffer put(int index, int c) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public IntBuffer put(IntBuffer buf) {
throw new ReadOnlyBufferException();
}
+ @Override
public final IntBuffer put(int[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public IntBuffer slice() {
return new ReadOnlyIntArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadOnlyLongArrayBuffer.java b/nio/src/main/java/java/nio/ReadOnlyLongArrayBuffer.java
index 76c1a4a..671f84f 100644
--- a/nio/src/main/java/java/nio/ReadOnlyLongArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyLongArrayBuffer.java
@@ -44,50 +44,62 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public LongBuffer asReadOnlyBuffer() {
return duplicate();
}
+ @Override
public LongBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public LongBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
protected long[] protectedArray() {
throw new ReadOnlyBufferException();
}
+ @Override
protected int protectedArrayOffset() {
throw new ReadOnlyBufferException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public LongBuffer put(long c) {
throw new ReadOnlyBufferException();
}
+ @Override
public LongBuffer put(int index, long c) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public LongBuffer put(LongBuffer buf) {
throw new ReadOnlyBufferException();
}
+ @Override
public final LongBuffer put(long[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public LongBuffer slice() {
return new ReadOnlyLongArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadOnlyShortArrayBuffer.java b/nio/src/main/java/java/nio/ReadOnlyShortArrayBuffer.java
index 1a3bfd3..9730eb5 100644
--- a/nio/src/main/java/java/nio/ReadOnlyShortArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadOnlyShortArrayBuffer.java
@@ -44,50 +44,62 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public ShortBuffer asReadOnlyBuffer() {
return duplicate();
}
+ @Override
public ShortBuffer compact() {
throw new ReadOnlyBufferException();
}
+ @Override
public ShortBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return true;
}
+ @Override
protected short[] protectedArray() {
throw new ReadOnlyBufferException();
}
+ @Override
protected int protectedArrayOffset() {
throw new ReadOnlyBufferException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
-
+
+ @Override
public ShortBuffer put(ShortBuffer buf) {
throw new ReadOnlyBufferException();
}
+ @Override
public ShortBuffer put(short c) {
throw new ReadOnlyBufferException();
}
+ @Override
public ShortBuffer put(int index, short c) {
throw new ReadOnlyBufferException();
}
+ @Override
public final ShortBuffer put(short[] src, int off, int len) {
throw new ReadOnlyBufferException();
}
-
+
+ @Override
public ShortBuffer slice() {
return new ReadOnlyShortArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadWriteCharArrayBuffer.java b/nio/src/main/java/java/nio/ReadWriteCharArrayBuffer.java
index 08f79b2..584df53 100644
--- a/nio/src/main/java/java/nio/ReadWriteCharArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteCharArrayBuffer.java
@@ -51,10 +51,12 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public CharBuffer asReadOnlyBuffer() {
return ReadOnlyCharArrayBuffer.copy(this, mark);
}
+ @Override
public CharBuffer compact() {
System.arraycopy(backingArray, position + offset, backingArray, offset,
remaining());
@@ -64,26 +66,32 @@
return this;
}
+ @Override
public CharBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
protected char[] protectedArray() {
return backingArray;
}
+ @Override
protected int protectedArrayOffset() {
return offset;
}
+ @Override
protected boolean protectedHasArray() {
return true;
}
+ @Override
public CharBuffer put(char c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -92,6 +100,7 @@
return this;
}
+ @Override
public CharBuffer put(int index, char c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -100,19 +109,21 @@
return this;
}
+ @Override
public CharBuffer put(char[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)len + (long)off > length) {
+ if (off < 0 || len < 0 || (long) len + (long) off > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferOverflowException();
}
- System.arraycopy(src, off, backingArray, offset+position, len);
+ System.arraycopy(src, off, backingArray, offset + position, len);
position += len;
return this;
}
-
+
+ @Override
public CharBuffer slice() {
return new ReadWriteCharArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadWriteDirectByteBuffer.java b/nio/src/main/java/java/nio/ReadWriteDirectByteBuffer.java
index 95b4ebc..d976994 100644
--- a/nio/src/main/java/java/nio/ReadWriteDirectByteBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteDirectByteBuffer.java
@@ -65,17 +65,19 @@
int anOffset) {
super(new SafeAddress(address), aCapacity, anOffset);
}
-
+
// BEGIN android-added
int getAddress() {
return this.safeAddress.address.toInt();
}
// END android-added
-
+
+ @Override
public ByteBuffer asReadOnlyBuffer() {
return ReadOnlyDirectByteBuffer.copy(this, mark);
}
+ @Override
public ByteBuffer compact() {
PlatformAddress effectiveAddress = getEffectiveAddress();
effectiveAddress.offsetBytes(position).moveTo(effectiveAddress,
@@ -86,14 +88,17 @@
return this;
}
+ @Override
public ByteBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
public ByteBuffer put(byte value) {
if (position == limit) {
throw new BufferOverflowException();
@@ -102,6 +107,7 @@
return this;
}
+ @Override
public ByteBuffer put(int index, byte value) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -117,29 +123,26 @@
*
* @see java.nio.ByteBuffer#put(byte[], int, int)
*/
+ @Override
public ByteBuffer put(byte[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferOverflowException();
}
- if (isReadOnly()) {
- throw new ReadOnlyBufferException();
- }
- getBaseAddress().setByteArray(offset + position, src, off,
- len);
+ getBaseAddress().setByteArray(offset + position, src, off, len);
position += len;
return this;
}
-
+
// BEGIN android-added
/**
* Writes <code>short</code>s in the given short array, starting from the
* specified offset, to the current position and increase the position by
* the number of <code>short</code>s written.
- *
+ *
* @param src
* The source short array
* @param off
@@ -179,7 +182,7 @@
* Writes <code>int</code>s in the given int array, starting from the
* specified offset, to the current position and increase the position by
* the number of <code>int</code>s written.
- *
+ *
* @param src
* The source int array
* @param off
@@ -215,7 +218,8 @@
return this;
}
// END android-added
-
+
+ @Override
public ByteBuffer putDouble(double value) {
int newPosition = position + 8;
if (newPosition > limit) {
@@ -226,14 +230,16 @@
return this;
}
+ @Override
public ByteBuffer putDouble(int index, double value) {
- if (index < 0 || (long)index + 8 > limit) {
+ if (index < 0 || (long) index + 8 > limit) {
throw new IndexOutOfBoundsException();
}
getBaseAddress().setDouble(offset + index, value, order);
return this;
}
+ @Override
public ByteBuffer putFloat(float value) {
int newPosition = position + 4;
if (newPosition > limit) {
@@ -244,14 +250,16 @@
return this;
}
+ @Override
public ByteBuffer putFloat(int index, float value) {
- if (index < 0 || (long)index + 4 > limit) {
+ if (index < 0 || (long) index + 4 > limit) {
throw new IndexOutOfBoundsException();
}
getBaseAddress().setFloat(offset + index, value, order);
return this;
}
+ @Override
public ByteBuffer putInt(int value) {
int newPosition = position + 4;
if (newPosition > limit) {
@@ -262,14 +270,16 @@
return this;
}
+ @Override
public ByteBuffer putInt(int index, int value) {
- if (index < 0 || (long)index + 4 > limit) {
+ if (index < 0 || (long) index + 4 > limit) {
throw new IndexOutOfBoundsException();
}
getBaseAddress().setInt(offset + index, value, order);
return this;
}
+ @Override
public ByteBuffer putLong(long value) {
int newPosition = position + 8;
if (newPosition > limit) {
@@ -280,14 +290,16 @@
return this;
}
+ @Override
public ByteBuffer putLong(int index, long value) {
- if (index < 0 || (long)index + 8 > limit) {
+ if (index < 0 || (long) index + 8 > limit) {
throw new IndexOutOfBoundsException();
}
getBaseAddress().setLong(offset + index, value, order);
return this;
}
+ @Override
public ByteBuffer putShort(short value) {
int newPosition = position + 2;
if (newPosition > limit) {
@@ -298,14 +310,16 @@
return this;
}
+ @Override
public ByteBuffer putShort(int index, short value) {
- if (index < 0 || (long)index + 2 > limit) {
+ if (index < 0 || (long) index + 2 > limit) {
throw new IndexOutOfBoundsException();
}
getBaseAddress().setShort(offset + index, value, order);
return this;
}
+ @Override
public ByteBuffer slice() {
ReadWriteDirectByteBuffer buf = new ReadWriteDirectByteBuffer(
safeAddress, remaining(), offset + position);
diff --git a/nio/src/main/java/java/nio/ReadWriteDoubleArrayBuffer.java b/nio/src/main/java/java/nio/ReadWriteDoubleArrayBuffer.java
index 2933178..689f3a1 100644
--- a/nio/src/main/java/java/nio/ReadWriteDoubleArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteDoubleArrayBuffer.java
@@ -54,10 +54,12 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public DoubleBuffer asReadOnlyBuffer() {
return ReadOnlyDoubleArrayBuffer.copy(this, mark);
}
+ @Override
public DoubleBuffer compact() {
System.arraycopy(backingArray, position + offset, backingArray, offset,
remaining());
@@ -67,26 +69,32 @@
return this;
}
+ @Override
public DoubleBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
protected double[] protectedArray() {
return backingArray;
}
+ @Override
protected int protectedArrayOffset() {
return offset;
}
+ @Override
protected boolean protectedHasArray() {
return true;
}
+ @Override
public DoubleBuffer put(double c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -95,6 +103,7 @@
return this;
}
+ @Override
public DoubleBuffer put(int index, double c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -103,20 +112,21 @@
return this;
}
+ @Override
public DoubleBuffer put(double[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferOverflowException();
}
- System.arraycopy(src, off, backingArray, offset
- + position, len);
+ System.arraycopy(src, off, backingArray, offset + position, len);
position += len;
return this;
}
-
+
+ @Override
public DoubleBuffer slice() {
return new ReadWriteDoubleArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadWriteFloatArrayBuffer.java b/nio/src/main/java/java/nio/ReadWriteFloatArrayBuffer.java
index 49b0b11..50e8ce5 100644
--- a/nio/src/main/java/java/nio/ReadWriteFloatArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteFloatArrayBuffer.java
@@ -54,10 +54,12 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public FloatBuffer asReadOnlyBuffer() {
return ReadOnlyFloatArrayBuffer.copy(this, mark);
}
+ @Override
public FloatBuffer compact() {
System.arraycopy(backingArray, position + offset, backingArray, offset,
remaining());
@@ -67,26 +69,32 @@
return this;
}
+ @Override
public FloatBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
protected float[] protectedArray() {
return backingArray;
}
+ @Override
protected int protectedArrayOffset() {
return offset;
}
+ @Override
protected boolean protectedHasArray() {
return true;
}
+ @Override
public FloatBuffer put(float c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -95,6 +103,7 @@
return this;
}
+ @Override
public FloatBuffer put(int index, float c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -103,20 +112,21 @@
return this;
}
+ @Override
public FloatBuffer put(float[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferOverflowException();
}
- System.arraycopy(src, off, backingArray, offset
- + position, len);
+ System.arraycopy(src, off, backingArray, offset + position, len);
position += len;
return this;
}
-
+
+ @Override
public FloatBuffer slice() {
return new ReadWriteFloatArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadWriteHeapByteBuffer.java b/nio/src/main/java/java/nio/ReadWriteHeapByteBuffer.java
index af74054..677b439 100644
--- a/nio/src/main/java/java/nio/ReadWriteHeapByteBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteHeapByteBuffer.java
@@ -16,8 +16,6 @@
package java.nio;
-
-
/**
* HeapByteBuffer, ReadWriteHeapByteBuffer and ReadOnlyHeapByteBuffer compose
* the implementation of array based byte buffers.
@@ -53,10 +51,12 @@
super(backingArray, capacity, arrayOffset);
}
+ @Override
public ByteBuffer asReadOnlyBuffer() {
return ReadOnlyHeapByteBuffer.copy(this, mark);
}
+ @Override
public ByteBuffer compact() {
System.arraycopy(backingArray, position + offset, backingArray, offset,
remaining());
@@ -66,26 +66,32 @@
return this;
}
+ @Override
public ByteBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
protected byte[] protectedArray() {
return backingArray;
}
+ @Override
protected int protectedArrayOffset() {
return offset;
}
+ @Override
protected boolean protectedHasArray() {
return true;
}
+ @Override
public ByteBuffer put(byte b) {
if (position == limit) {
throw new BufferOverflowException();
@@ -94,6 +100,7 @@
return this;
}
+ @Override
public ByteBuffer put(int index, byte b) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -109,8 +116,9 @@
*
* @see java.nio.ByteBuffer#put(byte[], int, int)
*/
+ @Override
public ByteBuffer put(byte[] src, int off, int len) {
- if (off < 0 || len < 0 || (long)off + (long)len > src.length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > src.length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
@@ -119,28 +127,32 @@
if (isReadOnly()) {
throw new ReadOnlyBufferException();
}
- System.arraycopy(src, off, backingArray, offset
- + position, len);
+ System.arraycopy(src, off, backingArray, offset + position, len);
position += len;
return this;
}
-
+
+ @Override
public ByteBuffer putDouble(double value) {
return putLong(Double.doubleToRawLongBits(value));
}
+ @Override
public ByteBuffer putDouble(int index, double value) {
return putLong(index, Double.doubleToRawLongBits(value));
}
+ @Override
public ByteBuffer putFloat(float value) {
return putInt(Float.floatToIntBits(value));
}
+ @Override
public ByteBuffer putFloat(int index, float value) {
return putInt(index, Float.floatToIntBits(value));
}
+ @Override
public ByteBuffer putInt(int value) {
int newPosition = position + 4;
if (newPosition > limit) {
@@ -151,22 +163,25 @@
return this;
}
+ @Override
public ByteBuffer putInt(int index, int value) {
- if (index < 0 || (long)index + 4 > limit) {
+ if (index < 0 || (long) index + 4 > limit) {
throw new IndexOutOfBoundsException();
}
store(index, value);
return this;
}
+ @Override
public ByteBuffer putLong(int index, long value) {
- if (index < 0 || (long)index + 8 > limit) {
+ if (index < 0 || (long) index + 8 > limit) {
throw new IndexOutOfBoundsException();
}
store(index, value);
return this;
}
+ @Override
public ByteBuffer putLong(long value) {
int newPosition = position + 8;
if (newPosition > limit) {
@@ -177,14 +192,16 @@
return this;
}
+ @Override
public ByteBuffer putShort(int index, short value) {
- if (index < 0 || (long)index + 2 > limit) {
+ if (index < 0 || (long) index + 2 > limit) {
throw new IndexOutOfBoundsException();
}
store(index, value);
return this;
}
+ @Override
public ByteBuffer putShort(short value) {
int newPosition = position + 2;
if (newPosition > limit) {
@@ -195,6 +212,7 @@
return this;
}
+ @Override
public ByteBuffer slice() {
ReadWriteHeapByteBuffer slice = new ReadWriteHeapByteBuffer(
backingArray, remaining(), offset + position);
diff --git a/nio/src/main/java/java/nio/ReadWriteIntArrayBuffer.java b/nio/src/main/java/java/nio/ReadWriteIntArrayBuffer.java
index 005e45b..a4be0b5 100644
--- a/nio/src/main/java/java/nio/ReadWriteIntArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteIntArrayBuffer.java
@@ -51,10 +51,12 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public IntBuffer asReadOnlyBuffer() {
return ReadOnlyIntArrayBuffer.copy(this, mark);
}
+ @Override
public IntBuffer compact() {
System.arraycopy(backingArray, position + offset, backingArray, offset,
remaining());
@@ -64,26 +66,32 @@
return this;
}
+ @Override
public IntBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
protected int[] protectedArray() {
return backingArray;
}
+ @Override
protected int protectedArrayOffset() {
return offset;
}
+ @Override
protected boolean protectedHasArray() {
return true;
}
+ @Override
public IntBuffer put(int c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -92,6 +100,7 @@
return this;
}
+ @Override
public IntBuffer put(int index, int c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -100,20 +109,21 @@
return this;
}
+ @Override
public IntBuffer put(int[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferOverflowException();
}
- System.arraycopy(src, off, backingArray, offset
- + position, len);
+ System.arraycopy(src, off, backingArray, offset + position, len);
position += len;
return this;
}
-
+
+ @Override
public IntBuffer slice() {
return new ReadWriteIntArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadWriteLongArrayBuffer.java b/nio/src/main/java/java/nio/ReadWriteLongArrayBuffer.java
index ff2c588..2d8cdb0 100644
--- a/nio/src/main/java/java/nio/ReadWriteLongArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteLongArrayBuffer.java
@@ -51,10 +51,12 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public LongBuffer asReadOnlyBuffer() {
return ReadOnlyLongArrayBuffer.copy(this, mark);
}
+ @Override
public LongBuffer compact() {
System.arraycopy(backingArray, position + offset, backingArray, offset,
remaining());
@@ -64,26 +66,32 @@
return this;
}
+ @Override
public LongBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
protected long[] protectedArray() {
return backingArray;
}
+ @Override
protected int protectedArrayOffset() {
return offset;
}
+ @Override
protected boolean protectedHasArray() {
return true;
}
+ @Override
public LongBuffer put(long c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -92,6 +100,7 @@
return this;
}
+ @Override
public LongBuffer put(int index, long c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -100,20 +109,21 @@
return this;
}
+ @Override
public LongBuffer put(long[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferOverflowException();
}
- System.arraycopy(src, off, backingArray, offset
- + position, len);
+ System.arraycopy(src, off, backingArray, offset + position, len);
position += len;
return this;
}
-
+
+ @Override
public LongBuffer slice() {
return new ReadWriteLongArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ReadWriteShortArrayBuffer.java b/nio/src/main/java/java/nio/ReadWriteShortArrayBuffer.java
index 193bdb3..0abbaf4 100644
--- a/nio/src/main/java/java/nio/ReadWriteShortArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ReadWriteShortArrayBuffer.java
@@ -54,10 +54,12 @@
super(capacity, backingArray, arrayOffset);
}
+ @Override
public ShortBuffer asReadOnlyBuffer() {
return ReadOnlyShortArrayBuffer.copy(this, mark);
}
+ @Override
public ShortBuffer compact() {
System.arraycopy(backingArray, position + offset, backingArray, offset,
remaining());
@@ -67,26 +69,32 @@
return this;
}
+ @Override
public ShortBuffer duplicate() {
return copy(this, mark);
}
+ @Override
public boolean isReadOnly() {
return false;
}
+ @Override
protected short[] protectedArray() {
return backingArray;
}
+ @Override
protected int protectedArrayOffset() {
return offset;
}
+ @Override
protected boolean protectedHasArray() {
return true;
}
+ @Override
public ShortBuffer put(short c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -95,6 +103,7 @@
return this;
}
+ @Override
public ShortBuffer put(int index, short c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -103,19 +112,21 @@
return this;
}
+ @Override
public ShortBuffer put(short[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferOverflowException();
}
- System.arraycopy(src, off, backingArray, offset+position, len);
+ System.arraycopy(src, off, backingArray, offset + position, len);
position += len;
return this;
}
-
+
+ @Override
public ShortBuffer slice() {
return new ReadWriteShortArrayBuffer(remaining(), backingArray, offset
+ position);
diff --git a/nio/src/main/java/java/nio/ShortArrayBuffer.java b/nio/src/main/java/java/nio/ShortArrayBuffer.java
index 54f8adb4..e7d42a0 100644
--- a/nio/src/main/java/java/nio/ShortArrayBuffer.java
+++ b/nio/src/main/java/java/nio/ShortArrayBuffer.java
@@ -49,6 +49,7 @@
this.offset = offset;
}
+ @Override
public final short get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -56,6 +57,7 @@
return backingArray[offset + position++];
}
+ @Override
public final short get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -63,24 +65,26 @@
return backingArray[offset + index];
}
+ @Override
public final ShortBuffer get(short[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
throw new BufferUnderflowException();
}
- System.arraycopy(backingArray, offset + position, dest,
- off, len);
+ System.arraycopy(backingArray, offset + position, dest, off, len);
position += len;
return this;
}
-
+
+ @Override
public final boolean isDirect() {
return false;
}
+ @Override
public final ByteOrder order() {
return ByteOrder.nativeOrder();
}
diff --git a/nio/src/main/java/java/nio/ShortBuffer.java b/nio/src/main/java/java/nio/ShortBuffer.java
index 39f9ddf..22d1b25 100644
--- a/nio/src/main/java/java/nio/ShortBuffer.java
+++ b/nio/src/main/java/java/nio/ShortBuffer.java
@@ -21,7 +21,6 @@
* A buffer of shorts.
* <p>
* A short buffer can be created in either of the following ways:
- * </p>
* <ul>
* <li>{@link #allocate(int) Allocate} a new short array and create a buffer
* based on it;</li>
@@ -30,10 +29,9 @@
* <li>Use {@link java.nio.ByteBuffer#asShortBuffer() ByteBuffer.asShortBuffer}
* to create a short buffer based on a byte buffer.</li>
* </ul>
- *
- * @since Android 1.0
*/
-public abstract class ShortBuffer extends Buffer implements Comparable<ShortBuffer> {
+public abstract class ShortBuffer extends Buffer implements
+ Comparable<ShortBuffer> {
/**
* Creates a short buffer based on a newly allocated short array.
@@ -43,7 +41,6 @@
* @return the created short buffer.
* @throws IllegalArgumentException
* if {@code capacity} is less than zero.
- * @since Android 1.0
*/
public static ShortBuffer allocate(int capacity) {
if (capacity < 0) {
@@ -57,12 +54,10 @@
* <p>
* Calling this method has the same effect as
* {@code wrap(array, 0, array.length)}.
- * </p>
- *
+ *
* @param array
* the short array which the new buffer will be based on.
* @return the created short buffer.
- * @since Android 1.0
*/
public static ShortBuffer wrap(short[] array) {
return wrap(array, 0, array.length);
@@ -73,8 +68,7 @@
* <p>
* The new buffer's position will be {@code start}, limit will be
* {@code start + len}, capacity will be the length of the array.
- * </p>
- *
+ *
* @param array
* the short array which the new buffer will be based on.
* @param start
@@ -86,15 +80,14 @@
* @return the created short buffer.
* @exception IndexOutOfBoundsException
* if either {@code start} or {@code len} is invalid.
- * @since Android 1.0
*/
public static ShortBuffer wrap(short[] array, int start, int len) {
- if (array == null) {
- throw new NullPointerException();
- }
- if (start< 0 || len < 0 || (long)start + (long)len > array.length) {
- throw new IndexOutOfBoundsException();
- }
+ if (array == null) {
+ throw new NullPointerException();
+ }
+ if (start < 0 || len < 0 || (long) start + (long) len > array.length) {
+ throw new IndexOutOfBoundsException();
+ }
ShortBuffer buf = BufferFactory.newShortBuffer(array);
buf.position = start;
@@ -124,7 +117,6 @@
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final short[] array() {
return protectedArray();
@@ -136,14 +128,12 @@
* <p>
* The offset is the index of the array corresponding to the zero position
* of the buffer.
- * </p>
- *
+ *
* @return the offset of the short array which this buffer is based on.
* @exception ReadOnlyBufferException
* if this buffer is based on an array, but it is read-only.
* @exception UnsupportedOperationException
* if this buffer is not based on an array.
- * @since Android 1.0
*/
public final int arrayOffset() {
return protectedArrayOffset();
@@ -171,15 +161,12 @@
* The returned buffer is guaranteed to be a new instance, even if this
* buffer is read-only itself. The new buffer's position, limit, capacity
* and mark are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means this
* buffer's change of content will be visible to the new buffer. The two
* buffer's position, limit and mark are independent.
- * </p>
- *
+ *
* @return a read-only version of this buffer.
- * @since Android 1.0
*/
public abstract ShortBuffer asReadOnlyBuffer();
@@ -189,12 +176,10 @@
* The remaining shorts will be moved to the head of the buffer, starting
* from position zero. Then the position is set to {@code remaining()}; the
* limit is set to capacity; the mark is cleared.
- * </p>
- *
+ *
* @return this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ShortBuffer compact();
@@ -209,7 +194,6 @@
* greater than {@code otherBuffer}.
* @exception ClassCastException
* if {@code otherBuffer} is not a short buffer.
- * @since Android 1.0
*/
public int compareTo(ShortBuffer otherBuffer) {
int compareRemaining = (remaining() < otherBuffer.remaining()) ? remaining()
@@ -236,15 +220,12 @@
* The duplicated buffer's position, limit, capacity and mark are the same
* as this buffer. The duplicated buffer's read-only property and byte order
* are the same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
- *
+ *
* @return a duplicated buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract ShortBuffer duplicate();
@@ -254,14 +235,13 @@
* If {@code other} is not a short buffer then {@code false} is returned.
* Two short buffers are equal if and only if their remaining shorts are
* exactly the same. Position, limit, capacity and mark are not considered.
- * </p>
- *
+ *
* @param other
* the object to compare with this short buffer.
* @return {@code true} if this short buffer is equal to {@code other},
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof ShortBuffer)) {
return false;
@@ -289,7 +269,6 @@
* @return the short at the current position.
* @exception BufferUnderflowException
* if the position is equal or greater than limit.
- * @since Android 1.0
*/
public abstract short get();
@@ -299,14 +278,12 @@
* <p>
* Calling this method has the same effect as
* {@code get(dest, 0, dest.length)}.
- * </p>
- *
+ *
* @param dest
* the destination short array.
* @return this buffer.
* @exception BufferUnderflowException
* if {@code dest.length} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public ShortBuffer get(short[] dest) {
return get(dest, 0, dest.length);
@@ -330,11 +307,10 @@
* if either {@code off} or {@code len} is invalid.
* @exception BufferUnderflowException
* if {@code len} is greater than {@code remaining()}.
- * @since Android 1.0
*/
public ShortBuffer get(short[] dest, int off, int len) {
int length = dest.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
if (len > remaining()) {
@@ -354,17 +330,15 @@
* @return a short at the specified index.
* @exception IndexOutOfBoundsException
* if index is invalid.
- * @since Android 1.0
*/
public abstract short get(int index);
/**
* Indicates whether this buffer is based on a short array and is
* read/write.
- *
+ *
* @return {@code true} if this buffer is based on a short array and
* provides read/write access, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean hasArray() {
return protectedHasArray();
@@ -373,10 +347,10 @@
/**
* Calculates this buffer's hash code from the remaining chars. The
* position, limit, capacity and mark don't affect the hash code.
- *
+ *
* @return the hash code calculated from the remaining shorts.
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int myPosition = position;
int hash = 0;
@@ -393,10 +367,8 @@
* <p>
* A short buffer is direct if it is based on a byte buffer and the byte
* buffer is direct.
- * </p>
- *
+ *
* @return {@code true} if this buffer is direct, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isDirect();
@@ -406,11 +378,9 @@
* <p>
* If this buffer is not based on a byte buffer, then always return the
* platform's native byte order.
- * </p>
- *
+ *
* @return the byte order used by this buffer when converting shorts from/to
* bytes.
- * @since Android 1.0
*/
public abstract ByteOrder order();
@@ -446,7 +416,6 @@
* if position is equal or greater than limit.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ShortBuffer put(short s);
@@ -456,8 +425,7 @@
* <p>
* Calling this method has the same effect as
* {@code put(src, 0, src.length)}.
- * </p>
- *
+ *
* @param src
* the source short array.
* @return this buffer.
@@ -465,7 +433,6 @@
* if {@code remaining()} is less than {@code src.length}.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public final ShortBuffer put(short[] src) {
return put(src, 0, src.length);
@@ -491,14 +458,13 @@
* if either {@code off} or {@code len} is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public ShortBuffer put(short[] src, int off, int len) {
int length = src.length;
- if (off < 0 || len < 0 || (long)off + (long)len > length) {
+ if (off < 0 || len < 0 || (long) off + (long) len > length) {
throw new IndexOutOfBoundsException();
}
-
+
if (len > remaining()) {
throw new BufferOverflowException();
}
@@ -523,7 +489,6 @@
* if {@code src} is this buffer.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public ShortBuffer put(ShortBuffer src) {
if (src == this) {
@@ -551,7 +516,6 @@
* if index is invalid.
* @exception ReadOnlyBufferException
* if no changes may be made to the contents of this buffer.
- * @since Android 1.0
*/
public abstract ShortBuffer put(int index, short s);
@@ -563,15 +527,12 @@
* The new buffer's position will be 0, limit will be its capacity, and its
* mark is cleared. The new buffer's read-only property and byte order are
* same as this buffer's.
- * </p>
* <p>
* The new buffer shares its content with this buffer, which means either
* buffer's change of content will be visible to the other. The two buffer's
* position, limit and mark are independent.
- * </p>
*
* @return a sliced buffer that shares its content with this buffer.
- * @since Android 1.0
*/
public abstract ShortBuffer slice();
@@ -579,10 +540,10 @@
* Returns a string representing the state of this short buffer.
*
* @return a string representing the state of this short buffer.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append(getClass().getName());
buf.append(", status: capacity="); //$NON-NLS-1$
buf.append(capacity());
diff --git a/nio/src/main/java/java/nio/ShortToByteBufferAdapter.java b/nio/src/main/java/java/nio/ShortToByteBufferAdapter.java
index a608bc9..f2a795f 100644
--- a/nio/src/main/java/java/nio/ShortToByteBufferAdapter.java
+++ b/nio/src/main/java/java/nio/ShortToByteBufferAdapter.java
@@ -16,11 +16,8 @@
package java.nio;
-// BEGIN android-added
-// Copied from newer version of harmony
import org.apache.harmony.nio.internal.DirectBuffer;
import org.apache.harmony.luni.platform.PlatformAddress;
-// END android-added
/**
* This class wraps a byte buffer to be a short buffer.
@@ -33,12 +30,9 @@
* The adapter extends Buffer, thus has its own position and limit.</li>
* </ul>
* </p>
- *
*/
-// BEGIN android-changed
-// Copied from newer version of harmony
-final class ShortToByteBufferAdapter extends ShortBuffer implements DirectBuffer {
-// END android-changed
+final class ShortToByteBufferAdapter extends ShortBuffer implements
+ DirectBuffer {
static ShortBuffer wrap(ByteBuffer byteBuffer) {
return new ShortToByteBufferAdapter(byteBuffer.slice());
@@ -52,15 +46,12 @@
this.byteBuffer.clear();
}
-// BEGIN android-added
-// Copied from newer version of harmony
public int getByteCapacity() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getByteCapacity();
- } else {
- assert false : byteBuffer;
- return -1;
- }
+ return ((DirectBuffer) byteBuffer).getByteCapacity();
+ }
+ assert false : byteBuffer;
+ return -1;
}
public PlatformAddress getEffectiveAddress() {
@@ -70,47 +61,44 @@
effectiveDirectAddress = addr.toInt();
return addr;
// END android-changed
- } else {
- assert false : byteBuffer;
- return null;
}
+ assert false : byteBuffer;
+ return null;
}
public PlatformAddress getBaseAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getBaseAddress();
- } else {
- assert false : byteBuffer;
- return null;
+ return ((DirectBuffer) byteBuffer).getBaseAddress();
}
+ assert false : byteBuffer;
+ return null;
}
-
+
public boolean isAddressValid() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).isAddressValid();
- } else {
- assert false : byteBuffer;
- return false;
+ return ((DirectBuffer) byteBuffer).isAddressValid();
}
+ assert false : byteBuffer;
+ return false;
}
public void addressValidityCheck() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).addressValidityCheck();
+ ((DirectBuffer) byteBuffer).addressValidityCheck();
} else {
assert false : byteBuffer;
}
}
-
+
public void free() {
if (byteBuffer instanceof DirectBuffer) {
- ((DirectBuffer)byteBuffer).free();
+ ((DirectBuffer) byteBuffer).free();
} else {
assert false : byteBuffer;
- }
+ }
}
- // END android-added
+ @Override
public ShortBuffer asReadOnlyBuffer() {
ShortToByteBufferAdapter buf = new ShortToByteBufferAdapter(byteBuffer
.asReadOnlyBuffer());
@@ -120,6 +108,7 @@
return buf;
}
+ @Override
public ShortBuffer compact() {
if (byteBuffer.isReadOnly()) {
throw new ReadOnlyBufferException();
@@ -134,6 +123,7 @@
return this;
}
+ @Override
public ShortBuffer duplicate() {
ShortToByteBufferAdapter buf = new ShortToByteBufferAdapter(byteBuffer
.duplicate());
@@ -143,6 +133,7 @@
return buf;
}
+ @Override
public short get() {
if (position == limit) {
throw new BufferUnderflowException();
@@ -150,6 +141,7 @@
return byteBuffer.getShort(position++ << 1);
}
+ @Override
public short get(int index) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -157,30 +149,37 @@
return byteBuffer.getShort(index << 1);
}
+ @Override
public boolean isDirect() {
return byteBuffer.isDirect();
}
+ @Override
public boolean isReadOnly() {
return byteBuffer.isReadOnly();
}
+ @Override
public ByteOrder order() {
return byteBuffer.order();
}
+ @Override
protected short[] protectedArray() {
throw new UnsupportedOperationException();
}
+ @Override
protected int protectedArrayOffset() {
throw new UnsupportedOperationException();
}
+ @Override
protected boolean protectedHasArray() {
return false;
}
+ @Override
public ShortBuffer put(short c) {
if (position == limit) {
throw new BufferOverflowException();
@@ -189,6 +188,7 @@
return this;
}
+ @Override
public ShortBuffer put(int index, short c) {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException();
@@ -196,7 +196,7 @@
byteBuffer.putShort(index << 1, c);
return this;
}
-
+
// BEGIN android-added
@Override
public ShortBuffer put(short[] s, int off, int len) {
@@ -212,6 +212,7 @@
}
// END android-added
+ @Override
public ShortBuffer slice() {
byteBuffer.limit(limit << 1);
byteBuffer.position(position << 1);
diff --git a/nio/src/main/java/java/nio/channels/AlreadyConnectedException.java b/nio/src/main/java/java/nio/channels/AlreadyConnectedException.java
index d558492..5e09b1c 100644
--- a/nio/src/main/java/java/nio/channels/AlreadyConnectedException.java
+++ b/nio/src/main/java/java/nio/channels/AlreadyConnectedException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* An {@code AlreadyConnectedException} is thrown when an attempt is made to
* connect a SocketChannel that is already connected.
- *
- * @since Android 1.0
*/
public class AlreadyConnectedException extends IllegalStateException {
@@ -29,8 +26,6 @@
/**
* Constructs an {@code AlreadyConnectedException}.
- *
- * @since Android 1.0
*/
public AlreadyConnectedException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/AsynchronousCloseException.java b/nio/src/main/java/java/nio/channels/AsynchronousCloseException.java
index e34d8d0..c2d285a 100644
--- a/nio/src/main/java/java/nio/channels/AsynchronousCloseException.java
+++ b/nio/src/main/java/java/nio/channels/AsynchronousCloseException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* An {@code AsynchronousCloseException} is thrown when the underlying channel
* for an I/O operation is closed by another thread.
- *
- * @since Android 1.0
*/
public class AsynchronousCloseException extends ClosedChannelException {
@@ -29,11 +26,8 @@
/**
* Constructs an {@code AsynchronousCloseException}.
- *
- * @since Android 1.0
*/
public AsynchronousCloseException() {
super();
}
-
}
diff --git a/nio/src/main/java/java/nio/channels/ByteChannel.java b/nio/src/main/java/java/nio/channels/ByteChannel.java
index 97f5d23..383d350 100644
--- a/nio/src/main/java/java/nio/channels/ByteChannel.java
+++ b/nio/src/main/java/java/nio/channels/ByteChannel.java
@@ -16,17 +16,14 @@
package java.nio.channels;
-
/**
* A ByteChannel is both readable and writable.
* <p>
* The methods for the byte channel are precisely those defined by readable and
* writable byte channels.
- * </p>
- *
+ *
* @see ReadableByteChannel
* @see WritableByteChannel
- * @since Android 1.0
*/
public interface ByteChannel extends ReadableByteChannel, WritableByteChannel {
// No methods defined.
diff --git a/nio/src/main/java/java/nio/channels/CancelledKeyException.java b/nio/src/main/java/java/nio/channels/CancelledKeyException.java
index ebb7c76..e955b3c 100644
--- a/nio/src/main/java/java/nio/channels/CancelledKeyException.java
+++ b/nio/src/main/java/java/nio/channels/CancelledKeyException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* A {@code CancelledKeyException} is thrown when an invalid selection key is
* used.
- *
- * @since Android 1.0
*/
public class CancelledKeyException extends IllegalStateException {
@@ -32,8 +29,6 @@
/**
* Constructs a {@code CancelledKeyException}.
- *
- * @since Android 1.0
*/
public CancelledKeyException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/Channel.java b/nio/src/main/java/java/nio/channels/Channel.java
index 585ce29..f31c565 100644
--- a/nio/src/main/java/java/nio/channels/Channel.java
+++ b/nio/src/main/java/java/nio/channels/Channel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.Closeable;
import java.io.IOException;
@@ -27,13 +26,9 @@
* Channels are open upon creation, and can be closed explicitly. Once a channel
* is closed it cannot be re-opened, and any attempts to perform I/O operations
* on the closed channel result in a <code>ClosedChannelException</code>.
- * </p>
* <p>
* Particular implementations or sub-interfaces of {@code Channel} dictate
* whether they are thread-safe or not.
- * </p>
- *
- * @since Android 1.0
*/
public interface Channel extends Closeable {
@@ -41,7 +36,6 @@
* Returns whether this channel is open or not.
*
* @return true if the channel is open, otherwise returns false.
- * @since Android 1.0
*/
public boolean isOpen();
@@ -53,16 +47,13 @@
* <p>
* If an attempt is made to perform an operation on a closed channel then a
* {@link ClosedChannelException} will be thrown on that attempt.
- * </p>
* <p>
* If multiple threads attempt to simultaneously close a channel, then only
* one thread will run the closure code, and others will be blocked until
* the first returns.
- * </p>
- *
+ *
* @throws IOException
* if a problem occurs closing the channel.
- * @since Android 1.0
*/
public void close() throws IOException;
}
diff --git a/nio/src/main/java/java/nio/channels/Channels.java b/nio/src/main/java/java/nio/channels/Channels.java
index fa70dc0..f29ca74 100644
--- a/nio/src/main/java/java/nio/channels/Channels.java
+++ b/nio/src/main/java/java/nio/channels/Channels.java
@@ -32,14 +32,9 @@
/**
* This class provides several utilities to get I/O streams from channels.
- *
- * @since Android 1.0
*/
public final class Channels {
- // -------------------------------------------------------------------
- // Constructor
- // -------------------------------------------------------------------
/*
* Not intended to be instantiated.
*/
@@ -47,10 +42,6 @@
super();
}
- // -------------------------------------------------------------------
- // Public Methods
- // -------------------------------------------------------------------
-
/**
* Returns an input stream on the given channel. The resulting stream has
* the following properties:
@@ -67,7 +58,6 @@
* @param channel
* the channel to be wrapped by an InputStream.
* @return an InputStream that takes bytes from the given byte channel.
- * @since Android 1.0
*/
public static InputStream newInputStream(ReadableByteChannel channel) {
return new ReadableByteChannelInputStream(channel);
@@ -88,7 +78,6 @@
* @param channel
* the channel to be wrapped by an OutputStream.
* @return an OutputStream that puts bytes onto the given byte channel.
- * @since Android 1.0
*/
public static OutputStream newOutputStream(WritableByteChannel channel) {
return new WritableByteChannelOutputStream(channel);
@@ -106,7 +95,6 @@
* @param inputStream
* the stream to be wrapped by a byte channel.
* @return a byte channel that reads bytes from the input stream.
- * @since Android 1.0
*/
public static ReadableByteChannel newChannel(InputStream inputStream) {
return new ReadableByteChannelImpl(inputStream);
@@ -121,11 +109,10 @@
* well.</li>
* <li>It is not buffered.</li>
* </ul>
- *
+ *
* @param outputStream
* the stream to be wrapped by a byte channel.
* @return a byte channel that writes bytes to the output stream.
- * @since Android 1.0
*/
public static WritableByteChannel newChannel(OutputStream outputStream) {
return new WritableByteChannelImpl(outputStream);
@@ -142,12 +129,10 @@
* The minimum size of the byte buffer, -1 means to use the
* default size.
* @return the reader.
- * @since Android 1.0
*/
public static Reader newReader(ReadableByteChannel channel,
CharsetDecoder decoder, int minBufferCapacity) {
- return new ByteChannelReader(
- new ReaderInputStream(channel), decoder,
+ return new ByteChannelReader(new ReaderInputStream(channel), decoder,
minBufferCapacity);
}
@@ -162,7 +147,6 @@
* @return the reader.
* @throws java.nio.charset.UnsupportedCharsetException
* if the given charset name is not supported.
- * @since Android 1.0
*/
public static Reader newReader(ReadableByteChannel channel,
String charsetName) {
@@ -181,7 +165,6 @@
* the minimum size of the byte buffer, -1 means to use the
* default size.
* @return the writer.
- * @since Android 1.0
*/
public static Writer newWriter(WritableByteChannel channel,
CharsetEncoder encoder, int minBufferCapacity) {
@@ -201,16 +184,12 @@
* @return the writer.
* @throws java.nio.charset.UnsupportedCharsetException
* if the given charset name is not supported.
- * @since Android 1.0
*/
public static Writer newWriter(WritableByteChannel channel,
String charsetName) {
return newWriter(channel, Charset.forName(charsetName).newEncoder(), -1);
}
- // -------------------------------------------------------------------
- // share routine
- // -------------------------------------------------------------------
/*
* wrap a byte array to a ByteBuffer
*/
@@ -223,10 +202,6 @@
return buffer;
}
- // -------------------------------------------------------------------
- // Wrapper classes
- // -------------------------------------------------------------------
-
private static class ChannelInputStream extends InputStream {
protected ReadableByteChannel channel;
@@ -236,9 +211,6 @@
channel = aChannel;
}
- /*
- * @see java.io.InputStream#read()
- */
@Override
public synchronized int read() throws IOException {
byte[] oneByte = new byte[1];
@@ -250,9 +222,6 @@
return -1;
}
- /*
- * @see java.io.InputStream#close()
- */
@Override
public synchronized void close() throws IOException {
channel.close();
@@ -265,16 +234,10 @@
private static class ReadableByteChannelInputStream extends
ChannelInputStream {
- /*
- * @param someChannel
- */
public ReadableByteChannelInputStream(ReadableByteChannel aChannel) {
super(aChannel);
}
- /*
- * @see java.io.InputStream#read(byte[], int, int)
- */
@Override
public synchronized int read(byte[] target, int offset, int length)
throws IOException {
@@ -301,16 +264,10 @@
*/
private static class ReaderInputStream extends ChannelInputStream {
- /*
- * @param someChannel
- */
public ReaderInputStream(ReadableByteChannel aChannel) {
super(aChannel);
}
- /*
- * @see java.io.InputStream#read(byte[], int, int)
- */
@Override
public synchronized int read(byte[] target, int offset, int length)
throws IOException {
@@ -333,26 +290,19 @@
private WritableByteChannel channel;
- /*
- * @param someChannel
- */
public WritableByteChannelOutputStream(WritableByteChannel aChannel) {
super();
channel = aChannel;
}
- /*
- * @see java.io.OutputStream#write(int)
- */
+ @Override
public synchronized void write(int oneByte) throws IOException {
byte[] wrappedByte = new byte[1];
wrappedByte[0] = (byte) oneByte;
write(wrappedByte);
}
- /*
- * @see java.io.OutputStream#write(byte[], int, int)
- */
+ @Override
public synchronized void write(byte[] source, int offset, int length)
throws IOException {
// avoid int overflow, check null source
@@ -371,9 +321,7 @@
channel.write(buffer);
}
- /*
- * @see java.io.OutputStream#close()
- */
+ @Override
public synchronized void close() throws IOException {
channel.close();
}
@@ -391,9 +339,6 @@
inputStream = aInputStream;
}
- /*
- * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
- */
public synchronized int read(ByteBuffer target) throws IOException {
if (!isOpen()) {
throw new ClosedChannelException();
@@ -413,9 +358,7 @@
return readCount;
}
- /*
- * @see java.nio.channels.spi.AbstractInterruptibleChannel#implCloseChannel()
- */
+ @Override
protected void implCloseChannel() throws IOException {
inputStream.close();
}
@@ -433,9 +376,6 @@
outputStream = aOutputStream;
}
- /*
- * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
- */
public synchronized int write(ByteBuffer source) throws IOException {
if (!isOpen()) {
throw new ClosedChannelException();
@@ -455,9 +395,7 @@
return bytesRemain;
}
- /*
- * @see java.nio.channels.spi.AbstractInterruptibleChannel#implCloseChannel()
- */
+ @Override
protected void implCloseChannel() throws IOException {
outputStream.close();
}
@@ -479,9 +417,6 @@
CharBuffer chars;
- /*
- * @param inputStream @param dec @param minBufferCapacity
- */
public ByteChannelReader(InputStream aInputStream,
CharsetDecoder aDecoder, int minBufferCapacity) {
super(aInputStream);
@@ -494,9 +429,7 @@
chars.limit(0);
}
- /*
- * @see java.io.Reader#close()
- */
+ @Override
public void close() throws IOException {
synchronized (lock) {
decoder = null;
@@ -507,9 +440,7 @@
}
}
- /*
- * @see java.io.Reader#ready()
- */
+ @Override
public boolean ready() {
synchronized (lock) {
if (null == inputStream) {
@@ -524,20 +455,16 @@
}
}
- /*
- * @see java.io.Reader#read()
- */
+ @Override
public int read() throws IOException {
- return IOUtil.readInputStreamReader(inputStream,
- bytes, chars, decoder, lock);
+ return IOUtil.readInputStreamReader(inputStream, bytes, chars,
+ decoder, lock);
}
- /*
- * @see java.io.Reader#read(char[], int, int)
- */
+ @Override
public int read(char[] buf, int offset, int length) throws IOException {
- return IOUtil.readInputStreamReader(buf, offset,
- length, inputStream, bytes, chars, decoder, lock);
+ return IOUtil.readInputStreamReader(buf, offset, length,
+ inputStream, bytes, chars, decoder, lock);
}
}
@@ -555,9 +482,6 @@
private ByteBuffer byteBuf;
- /*
- * @param outputStream @param enc @param minBufferCap
- */
public ByteChannelWriter(OutputStream aOutputStream,
CharsetEncoder aEncoder, int minBufferCap) {
super(aOutputStream);
@@ -567,9 +491,7 @@
encoder = aEncoder;
}
- /*
- * @see java.io.Writer#close()
- */
+ @Override
public void close() throws IOException {
synchronized (lock) {
if (encoder != null) {
@@ -582,37 +504,29 @@
}
}
- /*
- * @see java.io.Writer#flush()
- */
+ @Override
public void flush() throws IOException {
- IOUtil.flushOutputStreamWriter(outputStream,
+ IOUtil
+ .flushOutputStreamWriter(outputStream, byteBuf, encoder,
+ lock);
+ }
+
+ @Override
+ public void write(char[] buf, int offset, int count) throws IOException {
+ IOUtil.writeOutputStreamWriter(buf, offset, count, outputStream,
byteBuf, encoder, lock);
}
- /*
- * @see java.io.Writer#write(char[], int, int)
- */
- public void write(char[] buf, int offset, int count) throws IOException {
- IOUtil.writeOutputStreamWriter(buf, offset, count,
- outputStream, byteBuf, encoder, lock);
- }
-
- /*
- * @see java.io.Writer#write(int)
- */
+ @Override
public void write(int oneChar) throws IOException {
- IOUtil.writeOutputStreamWriter(oneChar,
- outputStream, byteBuf, encoder, lock);
+ IOUtil.writeOutputStreamWriter(oneChar, outputStream, byteBuf,
+ encoder, lock);
}
- /*
- * @see java.io.Writer#write(java.lang.String, int, int)
- */
+ @Override
public void write(String str, int offset, int count) throws IOException {
- IOUtil.writeOutputStreamWriter(str, offset, count,
- outputStream, byteBuf, encoder, lock);
+ IOUtil.writeOutputStreamWriter(str, offset, count, outputStream,
+ byteBuf, encoder, lock);
}
}
-
}
diff --git a/nio/src/main/java/java/nio/channels/ClosedByInterruptException.java b/nio/src/main/java/java/nio/channels/ClosedByInterruptException.java
index c7d5c6a..cc4c5eb 100644
--- a/nio/src/main/java/java/nio/channels/ClosedByInterruptException.java
+++ b/nio/src/main/java/java/nio/channels/ClosedByInterruptException.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
/**
* A {@code ClosedByInterruptException} is thrown when a thread is interrupted
* in a blocking I/O operation.
@@ -24,9 +23,6 @@
* When the thread is interrupted by a call to {@code interrupt()}, it closes
* the channel, sets the interrupt status of the thread to {@code true} and
* throws a {@code ClosedByInterruptException}.
- * </p>
- *
- * @since Android 1.0
*/
public class ClosedByInterruptException extends AsynchronousCloseException {
@@ -34,8 +30,6 @@
/**
* Constructs a {@code ClosedByInterruptException}.
- *
- * @since Android 1.0
*/
public ClosedByInterruptException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/ClosedChannelException.java b/nio/src/main/java/java/nio/channels/ClosedChannelException.java
index 4cf4b38..2b77601 100644
--- a/nio/src/main/java/java/nio/channels/ClosedChannelException.java
+++ b/nio/src/main/java/java/nio/channels/ClosedChannelException.java
@@ -16,14 +16,11 @@
package java.nio.channels;
-
import java.io.IOException;
/**
* A {@code ClosedChannelException} is thrown when a channel is closed for the
* type of operation attempted.
- *
- * @since Android 1.0
*/
public class ClosedChannelException extends IOException {
@@ -31,11 +28,8 @@
/**
* Constructs a {@code ClosedChannelException}.
- *
- * @since Android 1.0
*/
public ClosedChannelException() {
super();
}
-
}
diff --git a/nio/src/main/java/java/nio/channels/ClosedSelectorException.java b/nio/src/main/java/java/nio/channels/ClosedSelectorException.java
index 0fb16d3..5acc878 100644
--- a/nio/src/main/java/java/nio/channels/ClosedSelectorException.java
+++ b/nio/src/main/java/java/nio/channels/ClosedSelectorException.java
@@ -16,25 +16,18 @@
package java.nio.channels;
-
/**
* A {@code ClosedSelectorException} is thrown when a {@link Selector selector}
* is closed and an I/O operation is attempted.
- *
- * @since Android 1.0
*/
public class ClosedSelectorException extends IllegalStateException {
private static final long serialVersionUID = 6466297122317847835L;
-
+
/**
* Constructs a {@code ClosedSelectorException}.
- *
- * @since Android 1.0
*/
public ClosedSelectorException() {
super();
}
}
-
-
diff --git a/nio/src/main/java/java/nio/channels/ConnectionPendingException.java b/nio/src/main/java/java/nio/channels/ConnectionPendingException.java
index c535925..43ff65cd 100644
--- a/nio/src/main/java/java/nio/channels/ConnectionPendingException.java
+++ b/nio/src/main/java/java/nio/channels/ConnectionPendingException.java
@@ -16,13 +16,10 @@
package java.nio.channels;
-
/**
* A {@code ConnectionPendingException} is thrown when an attempt is made to
* connect a {@link SocketChannel} that has a non-blocking connection already
* underway.
- *
- * @since Android 1.0
*/
public class ConnectionPendingException extends IllegalStateException {
@@ -30,11 +27,8 @@
/**
* Constructs a {@code ConnectionPendingException}.
- *
- * @since Android 1.0
*/
public ConnectionPendingException() {
super();
}
-
}
diff --git a/nio/src/main/java/java/nio/channels/DatagramChannel.java b/nio/src/main/java/java/nio/channels/DatagramChannel.java
index 534155a..31b0825 100644
--- a/nio/src/main/java/java/nio/channels/DatagramChannel.java
+++ b/nio/src/main/java/java/nio/channels/DatagramChannel.java
@@ -37,13 +37,9 @@
* status until it is disconnected or closed. The benefit of a connected channel
* is the reduced effort of security checks during send and receive. When
* invoking {@code read} or {@code write}, a connected channel is required.
- * </p>
* <p>
* Datagram channels are thread-safe; only one thread can read or write at the
* same time.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class DatagramChannel extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
@@ -51,13 +47,12 @@
static {
Platform.getNetworkSystem().oneTimeInitialization(true);
}
-
+
/**
* Constructs a new {@code DatagramChannel}.
*
* @param selectorProvider
* an instance of SelectorProvider.
- * @since Android 1.0
*/
protected DatagramChannel(SelectorProvider selectorProvider) {
super(selectorProvider);
@@ -68,12 +63,10 @@
* <p>
* This channel is created by calling the <code>openDatagramChannel</code>
* method of the default {@link SelectorProvider} instance.
- * </p>
- *
+ *
* @return the new channel which is open but not connected.
* @throws IOException
* if some I/O error occurs.
- * @since Android 1.0
*/
public static DatagramChannel open() throws IOException {
return SelectorProvider.provider().openDatagramChannel();
@@ -86,8 +79,8 @@
*
* @see java.nio.channels.SelectableChannel#validOps()
* @return valid operations in bit-set.
- * @since Android 1.0
*/
+ @Override
public final int validOps() {
return (SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
@@ -98,7 +91,6 @@
* {@link DatagramSocket}.
*
* @return the related DatagramSocket instance.
- * @since Android 1.0
*/
public abstract DatagramSocket socket();
@@ -107,7 +99,6 @@
*
* @return <code>true</code> if this channel's socket is connected;
* <code>false</code> otherwise.
- * @since Android 1.0
*/
public abstract boolean isConnected();
@@ -120,12 +111,10 @@
* write operations being processed at the time the method is called. The
* connection status does not change until the channel is disconnected or
* closed.
- * </p>
* <p>
* This method executes the same security checks as the connect method of
* the {@link DatagramSocket} class.
- * </p>
- *
+ *
* @param address
* the address to be connected to.
* @return this channel.
@@ -143,7 +132,6 @@
* permitted to be accessed.
* @throws IOException
* if some other I/O error occurrs.
- * @since Android 1.0
*/
public abstract DatagramChannel connect(SocketAddress address)
throws IOException;
@@ -155,12 +143,10 @@
* This method can be called at any time without affecting the read and
* write operations being underway. It does not have any effect if the
* socket is not connected or the channel is closed.
- * </p>
- *
+ *
* @return this channel.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public abstract DatagramChannel disconnect() throws IOException;
@@ -174,16 +160,13 @@
* immediately. The transfer starts at the current position of the buffer,
* and if there is not enough space remaining in the buffer to store the
* datagram then the part of the datagram that does not fit is discarded.
- * </p>
* <p>
* This method can be called at any time and it will block if there is
* another thread that has started a read operation on the channel.
- * </p>
* <p>
* This method executes the same security checks as the receive method of
* the {@link DatagramSocket} class.
- * </p>
- *
+ *
* @param target
* the byte buffer to store the received datagram.
* @return the address of the datagram if the transfer is performed, or null
@@ -203,7 +186,6 @@
* permitted to be accessed.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public abstract SocketAddress receive(ByteBuffer target) throws IOException;
@@ -216,16 +198,13 @@
* in non-blocking mode then the datagram is only sent if there is enough
* space in the underlying output buffer at that moment. The transfer action
* is just like a regular write operation.
- * </p>
* <p>
* This method can be called at any time and it will block if another thread
* has started a send operation on this channel.
- * </p>
* <p>
* This method executes the same security checks as the send method of the
* {@link DatagramSocket} class.
- * </p>
- *
+ *
* @param source
* the byte buffer with the datagram to be sent.
* @param address
@@ -248,7 +227,6 @@
* permitted to access.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public abstract int send(ByteBuffer source, SocketAddress address)
throws IOException;
@@ -262,8 +240,7 @@
* not fit in the buffer is discarded. Otherwise, this method has the same
* behavior as the {@code read} method in the {@link ReadableByteChannel}
* interface.
- * </p>
- *
+ *
* @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
* @param target
* the byte buffer to store the received datagram.
@@ -282,7 +259,6 @@
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public abstract int read(ByteBuffer target) throws IOException;
@@ -295,8 +271,7 @@
* datagram that does not fit in the buffers is discarded. Otherwise, this
* method has the same behavior as the {@code read} method in the
* {@link ScatteringByteChannel} interface.
- * </p>
- *
+ *
* @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
* int, int)
* @param targets
@@ -324,7 +299,6 @@
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public abstract long read(ByteBuffer[] targets, int offset, int length)
throws IOException;
@@ -338,8 +312,7 @@
* datagram that does not fit in the buffers is discarded. Otherwise, this
* method has the same behavior as the {@code read} method in the
* {@link ScatteringByteChannel} interface.
- * </p>
- *
+ *
* @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
* @param targets
* the byte buffers to store the received datagram.
@@ -358,7 +331,6 @@
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public synchronized final long read(ByteBuffer[] targets)
throws IOException {
@@ -372,8 +344,7 @@
* and the datagram is sent to the connected address. Otherwise, this method
* has the same behavior as the {@code write} method in the
* {@link WritableByteChannel} interface.
- * </p>
- *
+ *
* @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
* @param source
* the byte buffer as the source of the datagram.
@@ -391,7 +362,6 @@
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public abstract int write(ByteBuffer source) throws IOException;
@@ -432,7 +402,6 @@
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public abstract long write(ByteBuffer[] sources, int offset, int length)
throws IOException;
@@ -465,7 +434,6 @@
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
- * @since Android 1.0
*/
public synchronized final long write(ByteBuffer[] sources)
throws IOException {
diff --git a/nio/src/main/java/java/nio/channels/FileChannel.java b/nio/src/main/java/java/nio/channels/FileChannel.java
index 0518fd3..2c30bae 100644
--- a/nio/src/main/java/java/nio/channels/FileChannel.java
+++ b/nio/src/main/java/java/nio/channels/FileChannel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
@@ -30,7 +29,6 @@
* does not have a method for opening files, since this behavior has been
* delegated to the {@link java.io.FileInputStream},
* {@link java.io.FileOutputStream} and {@link java.io.RandomAccessFile} types.
- * </p>
* <p>
* FileChannels created from a {@code FileInputStream} or a
* {@code RandomAccessFile} created in mode "r", are read-only. FileChannels
@@ -39,19 +37,16 @@
* FileChannels created from a {@code RandomAccessFile} that was opened in
* append-mode will also be in append-mode -- meaning that each write will be
* proceeded by a seek to the end of file.
- * </p>
* <p>
* FileChannels have a virtual pointer into the file which is referred to as a
* file <em>position</em>. The position can be manipulated by moving it
* within the file, and the current position can be queried.
- * </p>
* <p>
* FileChannels also have an associated <em>size</em>. The size of the file
* is the number of bytes that it currently contains. The size can be
* manipulated by adding more bytes to the end of the file (which increases the
* size) or truncating the file (which decreases the size). The current size can
* also be queried.
- * </p>
* <p>
* FileChannels have operations beyond the simple read, write, and close. They
* can also:
@@ -65,55 +60,41 @@
* <li>read and write to the file at absolute byte offsets in a fashion that
* does not modify the current position.</li>
* </ul>
- * </p>
* <p>
* FileChannels are thread-safe. Only one operation involving manipulation of
* the file position may be executed at the same time. Subsequent calls to such
* operations will block, and one of those blocked will be freed to continue
* when the first operation has completed. There is no ordered queue or fairness
* applied to the blocked threads.
- * </p>
* <p>
* It is undefined whether operations that do not manipulate the file position
* will also block when there are any other operations in-flight.
- * </p>
* <p>
* The logical view of the underlying file is consistent across all FileChannels
* and I/O streams opened on the same file by the same virtual machine process.
* Therefore, modifications performed via a channel will be visible to the
* stream and vice versa; this includes modifications to the file position,
* content, size, etc.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class FileChannel extends AbstractInterruptibleChannel
implements GatheringByteChannel, ScatteringByteChannel, ByteChannel {
/**
* {@code MapMode} defines file mapping mode constants.
- *
- * @since Android 1.0
*/
public static class MapMode {
/**
* Private mapping mode (equivalent to copy on write).
- *
- * @since Android 1.0
*/
public static final MapMode PRIVATE = new MapMode("PRIVATE"); //$NON-NLS-1$
/**
* Read-only mapping mode.
- *
- * @since Android 1.0
*/
public static final MapMode READ_ONLY = new MapMode("READ_ONLY"); //$NON-NLS-1$
/**
* Read-write mapping mode.
- *
- * @since Android 1.0
*/
public static final MapMode READ_WRITE = new MapMode("READ_WRITE"); //$NON-NLS-1$
@@ -132,8 +113,8 @@
* Returns a string version of the mapping mode.
*
* @return this map mode as string.
- * @since Android 1.0
*/
+ @Override
public String toString() {
return displayName;
}
@@ -141,8 +122,6 @@
/**
* Protected default constructor.
- *
- * @since Android 1.0
*/
protected FileChannel() {
super();
@@ -157,12 +136,10 @@
* local storage device. If the file is not hosted locally, for example on a
* networked file system, then applications cannot be certain that the
* modifications have been committed.
- * </p>
* <p>
* There are no assurances given that changes made to the file using methods
* defined elsewhere will be committed. For example, changes made via a
* mapped byte buffer may not be committed.
- * </p>
* <p>
* The <code>metadata</code> parameter indicates whether the update should
* include the file's metadata such as last modification time, last access
@@ -177,7 +154,6 @@
* if this channel is already closed.
* @throws IOException
* if another I/O error occurs.
- * @since Android 1.0
*/
public abstract void force(boolean metadata) throws IOException;
@@ -187,7 +163,7 @@
* This is a convenience method for acquiring a maximum length lock on a
* file. It is equivalent to:
* {@code fileChannel.lock(0L, Long.MAX_VALUE, false);}
- *
+ *
* @return the lock object representing the locked file area.
* @throws ClosedChannelException
* the file channel is closed.
@@ -206,7 +182,6 @@
* @throws IOException
* if another I/O error occurs while obtaining the requested
* lock.
- * @since Android 1.0
*/
public final FileLock lock() throws IOException {
return lock(0L, Long.MAX_VALUE, false);
@@ -217,41 +192,34 @@
* <p>
* This is the blocking version of lock acquisition, see also the
* <code>tryLock()</code> methods.
- * </p>
* <p>
* Attempts to acquire an overlapping lock region will fail. The attempt
* will fail if the overlapping lock has already been obtained, or if
* another thread is currently waiting to acquire the overlapping lock.
- * </p>
* <p>
* If the request is not for an overlapping lock, the thread calling this
* method will block until the lock is obtained (likely by no contention or
* another process releasing a lock), or until this thread is interrupted or
* the channel is closed.
- * </p>
* <p>
* If the lock is obtained successfully then the {@link FileLock} object
* returned represents the lock for subsequent operations on the locked
* region.
- * </p>
* <p>
* If the thread is interrupted while waiting for the lock, the thread is
* set to the interrupted state and throws a
* {@link FileLockInterruptionException}. If this channel is closed while
* the thread is waiting to obtain the lock then the thread throws a
* {@link AsynchronousCloseException}.
- * </p>
* <p>
* There is no requirement for the position and size to be within the
* current start and length of the file.
- * </p>
* <p>
* Some platforms do not support shared locks, and if a request is made for
* a shared lock on such a platform, this method will attempt to acquire an
* exclusive lock instead. It is undefined whether the lock obtained is
* advisory or mandatory.
- * </p>
- *
+ *
* @param position
* the starting position for the locked region.
* @param size
@@ -280,7 +248,6 @@
* the desired file lock.
* @throws IOException
* if another I/O error occurs.
- * @since Android 1.0
*/
public abstract FileLock lock(long position, long size, boolean shared)
throws IOException;
@@ -291,8 +258,7 @@
* channel do not affect the other storage place.
* <p>
* Note: mapping a file into memory is usually expensive.
- * </p>
- *
+ *
* @param mode
* one of the three mapping modes.
* @param position
@@ -312,7 +278,6 @@
* bigger than max integer.
* @throws IOException
* if any I/O error occurs.
- * @since Android 1.0
*/
public abstract MappedByteBuffer map(FileChannel.MapMode mode,
long position, long size) throws IOException;
@@ -326,7 +291,6 @@
* if this channel is closed.
* @throws IOException
* if another I/O error occurs.
- * @since Android 1.0
*/
public abstract long position() throws IOException;
@@ -349,7 +313,6 @@
* if this channel is closed.
* @throws IOException
* if another I/O error occurs.
- * @since Android 1.0
*/
public abstract FileChannel position(long offset) throws IOException;
@@ -359,16 +322,13 @@
* The maximum number of bytes that will be read is the remaining number of
* bytes in the buffer when the method is invoked. The bytes will be copied
* into the buffer starting at the buffer's current position.
- * </p>
* <p>
* The call may block if other threads are also attempting to read from this
* channel.
- * </p>
* <p>
* Upon completion, the buffer's position is set to the end of the bytes
* that have been read. The buffer's limit is not changed.
- * </p>
- *
+ *
* @param buffer
* the byte buffer to receive the bytes.
* @return the number of bytes actually read.
@@ -384,7 +344,6 @@
* @throws NonReadableChannelException
* if the channel has not been opened in a mode that permits
* reading.
- * @since Android 1.0
*/
public abstract int read(ByteBuffer buffer) throws IOException;
@@ -395,15 +354,12 @@
* The bytes are read starting at the given file position (up to the
* remaining number of bytes in the buffer). The number of bytes actually
* read is returned.
- * </p>
* <p>
* If {@code position} is beyond the current end of file, then no bytes are
* read.
- * </p>
* <p>
* Note that the file position is unmodified by this method.
- * </p>
- *
+ *
* @param buffer
* the buffer to receive the bytes.
* @param position
@@ -425,7 +381,6 @@
* @throws NonReadableChannelException
* if the channel has not been opened in a mode that permits
* reading.
- * @since Android 1.0
*/
public abstract int read(ByteBuffer buffer, long position)
throws IOException;
@@ -439,12 +394,10 @@
* <p>
* If a read operation is in progress, subsequent threads will block until
* the read is completed and will then contend for the ability to read.
- * </p>
* <p>
* Calling this method is equivalent to calling
* {@code read(buffers, 0, buffers.length);}
- * </p>
- *
+ *
* @param buffers
* the array of byte buffers into which the bytes will be copied.
* @return the number of bytes actually read.
@@ -461,24 +414,21 @@
* @throws NonReadableChannelException
* if the channel has not been opened in a mode that permits
* reading.
- * @since Android 1.0
*/
public final long read(ByteBuffer[] buffers) throws IOException {
return read(buffers, 0, buffers.length);
}
/**
- * Reads bytes from this file channel and stores them in a subset of the
- * specified array of buffers. The subset is defined by {@code start} and
- * {@code number}, indicating the first buffer and the number of buffers to
- * use. This method attempts to read as many bytes as can be stored in the
- * buffer subset from this channel and returns the number of bytes actually
- * read. It also increases the file position by the number of bytes read.
+ * Reads bytes from this file channel into a subset of the given buffers.
+ * This method attempts to read all {@code remaining()} bytes from {@code
+ * length} byte buffers, in order, starting at {@code targets[offset]}. It
+ * increases the file position by the number of bytes actually read. The
+ * number of bytes actually read is returned.
* <p>
* If a read operation is in progress, subsequent threads will block until
* the read is completed and will then contend for the ability to read.
- * </p>
- *
+ *
* @param buffers
* the array of byte buffers into which the bytes will be copied.
* @param start
@@ -503,7 +453,6 @@
* @throws NonReadableChannelException
* if the channel has not been opened in a mode that permits
* reading.
- * @since Android 1.0
*/
public abstract long read(ByteBuffer[] buffers, int start, int number)
throws IOException;
@@ -516,7 +465,6 @@
* if this channel is closed.
* @throws IOException
* if an I/O error occurs while getting the size of the file.
- * @since Android 1.0
*/
public abstract long size() throws IOException;
@@ -530,8 +478,7 @@
* buffer.
* <p>
* Note that this channel's position is not modified.
- * </p>
- *
+ *
* @param src
* the source channel to read bytes from.
* @param position
@@ -554,7 +501,6 @@
* if the thread is interrupted during this operation.
* @throws IOException
* if any I/O error occurs.
- * @since Android 1.0
*/
public abstract long transferFrom(ReadableByteChannel src, long position,
long count) throws IOException;
@@ -569,8 +515,7 @@
* buffer.
* <p>
* Note that this channel's position is not modified.
- * </p>
- *
+ *
* @param position
* the non-negative position to begin.
* @param count
@@ -593,7 +538,6 @@
* if the thread is interrupted during this operation.
* @throws IOException
* if any I/O error occurs.
- * @since Android 1.0
*/
public abstract long transferTo(long position, long count,
WritableByteChannel target) throws IOException;
@@ -605,8 +549,7 @@
* <p>
* If the file position is currently greater than the given size, then it is
* set to the new size.
- * </p>
- *
+ *
* @param size
* the maximum size of the underlying file.
* @throws IllegalArgumentException
@@ -618,7 +561,6 @@
* @throws IOException
* if another I/O error occurs.
* @return this channel.
- * @since Android 1.0
*/
public abstract FileChannel truncate(long size) throws IOException;
@@ -628,12 +570,10 @@
* This is a convenience method for attempting to acquire a maximum length
* lock on the file. It is equivalent to:
* {@code fileChannel.tryLock(0L, Long.MAX_VALUE, false);}
- * </p>
* <p>
* The method returns {@code null} if the acquisition would result in an
* overlapped lock with another OS process.
- * </p>
- *
+ *
* @return the file lock object, or {@code null} if the lock would overlap
* with an existing exclusive lock in another OS process.
* @throws ClosedChannelException
@@ -644,7 +584,6 @@
* with this request.
* @throws IOException
* if any I/O error occurs.
- * @since Android 1.0
*/
public final FileLock tryLock() throws IOException {
return tryLock(0L, Long.MAX_VALUE, false);
@@ -659,8 +598,7 @@
* outside of the file's size. The size of the lock is fixed. If the file
* grows outside of the lock that region of the file won't be locked by this
* lock.
- * </p>
- *
+ *
* @param position
* the starting position.
* @param size
@@ -679,7 +617,6 @@
* with this request.
* @throws IOException
* if any I/O error occurs.
- * @since Android 1.0
*/
public abstract FileLock tryLock(long position, long size, boolean shared)
throws IOException;
@@ -703,11 +640,11 @@
* if another thread closes the channel during the write.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while this
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws IOException
* if another I/O error occurs, details are in the message.
- * @since Android 1.0
+ * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
*/
public abstract int write(ByteBuffer src) throws IOException;
@@ -718,16 +655,13 @@
* The bytes are written starting at the given file position (up to the
* remaining number of bytes in the buffer). The number of bytes actually
* written is returned.
- * </p>
* <p>
* If the position is beyond the current end of file, then the file is first
* extended up to the given position by the required number of unspecified
* byte values.
- * </p>
* <p>
* Note that the file position is not modified by this method.
- * </p>
- *
+ *
* @param buffer
* the buffer containing the bytes to be written.
* @param position
@@ -748,7 +682,6 @@
* thread is set and the channel is closed.
* @throws IOException
* if another I/O error occurs.
- * @since Android 1.0
*/
public abstract int write(ByteBuffer buffer, long position)
throws IOException;
@@ -763,8 +696,7 @@
* <p>
* Calling this method is equivalent to calling
* {@code write(buffers, 0, buffers.length);}
- * </p>
- *
+ *
* @param buffers
* the buffers containing bytes to write.
* @return the number of bytes actually written.
@@ -773,7 +705,7 @@
* operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while this
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws ClosedChannelException
* if this channel is closed.
@@ -781,21 +713,20 @@
* if another I/O error occurs; details are in the message.
* @throws NonWritableChannelException
* if this channel was not opened for writing.
- * @since Android 1.0
*/
public final long write(ByteBuffer[] buffers) throws IOException {
return write(buffers, 0, buffers.length);
}
/**
- * Writes bytes from a subset of the specified array of buffers into this
- * file channel. The subset is defined by {@code offset} and {@code length},
- * indicating the first buffer and the number of buffers to use.
+ * Attempts to write a subset of the given bytes from the buffers to this
+ * file channel. This method attempts to write all {@code remaining()}
+ * bytes from {@code length} byte buffers, in order, starting at {@code
+ * sources[offset]}. The number of bytes actually written is returned.
* <p>
* If a write operation is in progress, subsequent threads will block until
* the write is completed and then contend for the ability to write.
- * </p>
- *
+ *
* @param buffers
* the array of byte buffers that is the source for bytes written
* to this channel.
@@ -810,7 +741,7 @@
* operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while this
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws ClosedChannelException
* if this channel is closed.
@@ -822,9 +753,7 @@
* if another I/O error occurs; details are in the message.
* @throws NonWritableChannelException
* if this channel was not opened for writing.
- * @since Android 1.0
*/
public abstract long write(ByteBuffer[] buffers, int offset, int length)
throws IOException;
-
}
diff --git a/nio/src/main/java/java/nio/channels/FileLock.java b/nio/src/main/java/java/nio/channels/FileLock.java
index e9aae1f..1bc71a8 100644
--- a/nio/src/main/java/java/nio/channels/FileLock.java
+++ b/nio/src/main/java/java/nio/channels/FileLock.java
@@ -30,7 +30,6 @@
* simultaneously hold a shared lock overlapping the exclusive lock. An
* application can determine whether a {@code FileLock} is shared or exclusive
* via the {@code isShared()} method.
- * </p>
* <p>
* Locks held by a particular process cannot overlap one another. Applications
* can determine whether a proposed lock will overlap by using the {@code
@@ -38,19 +37,16 @@
* locks held in this process. Locks are shared amongst all threads in the
* acquiring process, and are therefore unsuitable for intra-process
* synchronization.
- * </p>
* <p>
* Once a lock is acquired, it is immutable in all its state except {@code
* isValid()}. The lock will initially be valid, but may be rendered invalid by
* explicit removal of the lock, using {@code release()}, or implicitly by
* closing the channel or exiting the process (terminating the virtual machine).
- * </p>
* <h3>Platform dependencies</h3>
* <p>
* Locks are intended to be true platform operating system file locks, and
* therefore locks held by the virtual machine process will be visible to other
* operating system processes.
- * </p>
* <p>
* The characteristics of the underlying operating system locks will show
* through in the Java implementation. For example, some platforms' locks are
@@ -61,7 +57,6 @@
* processes to not play well. To be on the safe side, it is best to assume that
* the platform is adopting advisory locks and always acquire shared locks when
* reading a region of a file.
- * </p>
* <p>
* On some platforms, the presence of a lock will prevent the file from being
* memory-mapped. On some platforms, closing a channel on a given file handle
@@ -69,13 +64,9 @@
* channels open on the same file; their locks will also be released. The safe
* option here is to ensure that you only acquire locks on a single channel for
* a particular file and that becomes the synchronization point.
- * </p>
* <p>
* Further care should be exercised when locking files maintained on network
* file systems, since they often have further limitations.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class FileLock {
@@ -104,7 +95,6 @@
* @param shared
* the lock's sharing mode of lock; {@code true} is shared,
* {@code false} is exclusive.
- * @since Android 1.0
*/
protected FileLock(FileChannel channel, long position, long size,
boolean shared) {
@@ -122,7 +112,6 @@
* Returns the lock's {@link FileChannel}.
*
* @return the channel.
- * @since Android 1.0
*/
public final FileChannel channel() {
return channel;
@@ -132,7 +121,6 @@
* Returns the lock's starting position in the file.
*
* @return the lock position.
- * @since Android 1.0
*/
public final long position() {
return position;
@@ -142,7 +130,6 @@
* Returns the length of the file lock in bytes.
*
* @return the size of the file lock in bytes.
- * @since Android 1.0
*/
public final long size() {
return size;
@@ -154,7 +141,6 @@
*
* @return {@code true} if the lock is a shared lock, {@code false} if it is
* exclusive.
- * @since Android 1.0
*/
public final boolean isShared() {
return shared;
@@ -169,7 +155,6 @@
* @param length
* the length of the comparative lock.
* @return {@code true} if there is an overlap, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean overlaps(long start, long length) {
final long end = position + size - 1;
@@ -186,7 +171,6 @@
* explicitly released.
*
* @return {@code true} if the lock is valid, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isValid();
@@ -199,7 +183,6 @@
* the lock is made.
* @throws IOException
* if another I/O error occurs.
- * @since Android 1.0
*/
public abstract void release() throws IOException;
@@ -208,17 +191,18 @@
* to an end user.
*
* @return the display string.
- * @since Android 1.0
*/
+ @Override
+ @SuppressWarnings("nls")
public final String toString() {
- StringBuffer buffer = new StringBuffer(64); // Guess length of string
- buffer.append("FileLock: [position="); //$NON-NLS-1$
+ StringBuilder buffer = new StringBuilder(64); // Guess length of string
+ buffer.append("FileLock: [position=");
buffer.append(position);
- buffer.append(", size="); //$NON-NLS-1$
+ buffer.append(", size=");
buffer.append(size);
- buffer.append(", shared="); //$NON-NLS-1$
+ buffer.append(", shared=");
buffer.append(Boolean.toString(shared));
- buffer.append("]"); //$NON-NLS-1$
+ buffer.append("]");
return buffer.toString();
}
}
diff --git a/nio/src/main/java/java/nio/channels/FileLockInterruptionException.java b/nio/src/main/java/java/nio/channels/FileLockInterruptionException.java
index 0920f52..71cc0c6 100644
--- a/nio/src/main/java/java/nio/channels/FileLockInterruptionException.java
+++ b/nio/src/main/java/java/nio/channels/FileLockInterruptionException.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
/**
@@ -24,9 +23,6 @@
* interrupted while waiting to acquire a file lock.
* <p>
* Note that the thread will also be in the 'interrupted' state.
- * </p>
- *
- * @since Android 1.0
*/
public class FileLockInterruptionException extends IOException {
@@ -34,8 +30,6 @@
/**
* Constructs a {@code FileLockInterruptionException}.
- *
- * @since Android 1.0
*/
public FileLockInterruptionException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/GatheringByteChannel.java b/nio/src/main/java/java/nio/channels/GatheringByteChannel.java
index e8a6c73..8e52075 100644
--- a/nio/src/main/java/java/nio/channels/GatheringByteChannel.java
+++ b/nio/src/main/java/java/nio/channels/GatheringByteChannel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -24,8 +23,6 @@
* The interface for channels that can write a set of buffers in a single
* operation. The corresponding interface for read operations is
* {@link ScatteringByteChannel}.
- *
- * @since Android 1.0
*/
public interface GatheringByteChannel extends WritableByteChannel {
@@ -33,8 +30,7 @@
* Writes bytes from all the given buffers to a channel.
* <p>
* This method is equivalent to: {@code write(buffers, 0, buffers.length);}
- * </p>
- *
+ *
* @param buffers
* the buffers containing bytes to be written.
* @return the number of bytes actually written.
@@ -43,7 +39,7 @@
* operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws ClosedChannelException
* if the channel is closed.
@@ -56,19 +52,17 @@
* @throws NonWritableChannelException
* if the channel has not been opened in a mode that permits
* writing.
- * @since Android 1.0
*/
public long write(ByteBuffer[] buffers) throws IOException;
/**
- * Writes bytes from a subset of the specified array of buffers to a
- * channel. The subset is defined by {@code offset} and {@code length},
- * indicating the first buffer and the number of buffers to use.
+ * Attempts to write all <code>remaining()</code> bytes from {@code length}
+ * byte buffers, in order, starting at {@code buffers[offset]}. The number
+ * of bytes actually written is returned.
* <p>
* If a write operation is in progress, subsequent threads will block until
* the write is completed and then contend for the ability to write.
- * </p>
- *
+ *
* @param buffers
* the array of byte buffers that is the source for bytes written
* to the channel.
@@ -83,7 +77,7 @@
* operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws ClosedChannelException
* if the channel is closed.
@@ -95,7 +89,6 @@
* if another I/O error occurs; details are in the message.
* @throws NonWritableChannelException
* if the channel was not opened for writing.
- * @since Android 1.0
*/
public long write(ByteBuffer[] buffers, int offset, int length)
throws IOException;
diff --git a/nio/src/main/java/java/nio/channels/IllegalBlockingModeException.java b/nio/src/main/java/java/nio/channels/IllegalBlockingModeException.java
index 3efd94a..5495321 100644
--- a/nio/src/main/java/java/nio/channels/IllegalBlockingModeException.java
+++ b/nio/src/main/java/java/nio/channels/IllegalBlockingModeException.java
@@ -16,13 +16,10 @@
package java.nio.channels;
-
/**
* An {@code IllegalBlockingModeException} is thrown when an operation that
* requires a specific blocking mode is invoked on a channel that is in a
* different blocking mode.
- *
- * @since Android 1.0
*/
public class IllegalBlockingModeException extends IllegalStateException {
@@ -30,8 +27,6 @@
/**
* Constructs a {@code IllegalBlockingModeException}.
- *
- * @since Android 1.0
*/
public IllegalBlockingModeException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/IllegalSelectorException.java b/nio/src/main/java/java/nio/channels/IllegalSelectorException.java
index 0cffd22..a40e2cb 100644
--- a/nio/src/main/java/java/nio/channels/IllegalSelectorException.java
+++ b/nio/src/main/java/java/nio/channels/IllegalSelectorException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* An {@code IllegalSelectorException} is thrown when a call is made to register
* a channel on a selector that has been created by a different provider.
- *
- * @since Android 1.0
*/
public class IllegalSelectorException extends IllegalArgumentException {
@@ -29,11 +26,8 @@
/**
* Constructs a {@code IllegalSelectorException}.
- *
- * @since Android 1.0
*/
public IllegalSelectorException() {
super();
}
-
}
diff --git a/nio/src/main/java/java/nio/channels/InterruptibleChannel.java b/nio/src/main/java/java/nio/channels/InterruptibleChannel.java
index 0375618..b871c41 100644
--- a/nio/src/main/java/java/nio/channels/InterruptibleChannel.java
+++ b/nio/src/main/java/java/nio/channels/InterruptibleChannel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
/**
@@ -27,7 +26,6 @@
* an I/O operation (the I/O thread) can be released by another thread calling
* the channel's {@link #close()} method. The I/O thread will throw an
* {@link AsynchronousCloseException} and the channel will be closed.
- * </p>
* <p>
* A channel that is interruptible permits a thread blocked on an I/O operation
* (the I/O thread) to be interrupted by another thread (by invoking
@@ -36,8 +34,6 @@
* its interrupted status set and the channel will be closed. If the I/O thread
* attempts to make an I/O call with the interrupt status set the call will
* immediately fail with a {@link ClosedByInterruptException}.
- *
- * @since Android 1.0
*/
public interface InterruptibleChannel extends Channel {
@@ -47,12 +43,9 @@
* Any threads that are blocked on I/O operations on this channel will be
* interrupted with an {@link AsynchronousCloseException}. Otherwise, this
* method behaves the same as defined in the {@code Channel} interface.
- * </p>
*
* @throws IOException
* if an I/O error occurs while closing the channel.
- * @since Android 1.0
*/
public void close() throws IOException;
-
}
diff --git a/nio/src/main/java/java/nio/channels/NoConnectionPendingException.java b/nio/src/main/java/java/nio/channels/NoConnectionPendingException.java
index 3434b87..34b3e5a 100644
--- a/nio/src/main/java/java/nio/channels/NoConnectionPendingException.java
+++ b/nio/src/main/java/java/nio/channels/NoConnectionPendingException.java
@@ -16,15 +16,12 @@
package java.nio.channels;
-
/**
* A {@code NoConnectionPendingException} is thrown if {@code SocketChannel}'s
* {@link SocketChannel#finishConnect() finishConnect} method is called before
- * the {@code SocketChannel}'s
- * {@link SocketChannel#connect(SocketAddress) connect} method completed without
- * error.
- *
- * @since Android 1.0
+ * the {@code SocketChannel}'s {@link
+ * SocketChannel#connect(java.net.SocketAddress)} connect} method completed
+ * without error.
*/
public class NoConnectionPendingException extends IllegalStateException {
@@ -32,8 +29,6 @@
/**
* Constructs a {@code NoConnectionPendingException}.
- *
- * @since Android 1.0
*/
public NoConnectionPendingException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/NonReadableChannelException.java b/nio/src/main/java/java/nio/channels/NonReadableChannelException.java
index c436682..51e3cd3 100644
--- a/nio/src/main/java/java/nio/channels/NonReadableChannelException.java
+++ b/nio/src/main/java/java/nio/channels/NonReadableChannelException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* A {@code NonReadableChannelException} is thrown when attempting to read from
* a channel that is not open for reading.
- *
- * @since Android 1.0
*/
public class NonReadableChannelException extends IllegalStateException {
@@ -29,8 +26,6 @@
/**
* Constructs a {@code NonReadableChannelException}.
- *
- * @since Android 1.0
*/
public NonReadableChannelException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/NonWritableChannelException.java b/nio/src/main/java/java/nio/channels/NonWritableChannelException.java
index 81549cb..acc6305 100644
--- a/nio/src/main/java/java/nio/channels/NonWritableChannelException.java
+++ b/nio/src/main/java/java/nio/channels/NonWritableChannelException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* A {@code NonWritableChannelException} is thrown when attempting to write to a
* channel that is not open for writing.
- *
- * @since Android 1.0
*/
public class NonWritableChannelException extends IllegalStateException {
@@ -29,8 +26,6 @@
/**
* Constructs a {@code NonWritableChannelException}.
- *
- * @since Android 1.0
*/
public NonWritableChannelException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/NotYetBoundException.java b/nio/src/main/java/java/nio/channels/NotYetBoundException.java
index 2210903..d2ffc55 100644
--- a/nio/src/main/java/java/nio/channels/NotYetBoundException.java
+++ b/nio/src/main/java/java/nio/channels/NotYetBoundException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* A {@code NotYetBoundException} is thrown if the server socket channel is not
* bound before an I/O operation is made.
- *
- * @since Android 1.0
*/
public class NotYetBoundException extends IllegalStateException {
@@ -29,8 +26,6 @@
/**
* Constructs a {@code NotYetBoundException}.
- *
- * @since Android 1.0
*/
public NotYetBoundException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/NotYetConnectedException.java b/nio/src/main/java/java/nio/channels/NotYetConnectedException.java
index 393c77f..da3523a 100644
--- a/nio/src/main/java/java/nio/channels/NotYetConnectedException.java
+++ b/nio/src/main/java/java/nio/channels/NotYetConnectedException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* A {@code NotYetConnectedException} is thrown if the socket channel is not
* connected before an I/O operation is invoked.
- *
- * @since Android 1.0
*/
public class NotYetConnectedException extends IllegalStateException {
@@ -29,11 +26,8 @@
/**
* Constructs a {@code NotYetConnectedException}.
- *
- * @since Android 1.0
*/
public NotYetConnectedException() {
super();
}
-
}
diff --git a/nio/src/main/java/java/nio/channels/OverlappingFileLockException.java b/nio/src/main/java/java/nio/channels/OverlappingFileLockException.java
index 6a00a6b..98fab94 100644
--- a/nio/src/main/java/java/nio/channels/OverlappingFileLockException.java
+++ b/nio/src/main/java/java/nio/channels/OverlappingFileLockException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* An {@code OverlappingFileLockException} is thrown when attempting to acquire
* a lock that overlaps an existing or pending lock held by this process.
- *
- * @since Android 1.0
*/
public class OverlappingFileLockException extends IllegalStateException {
@@ -29,8 +26,6 @@
/**
* Constructs a {@code OverlappingFileLockException}.
- *
- * @since Android 1.0
*/
public OverlappingFileLockException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/Pipe.java b/nio/src/main/java/java/nio/channels/Pipe.java
index e28812c..956e69b 100644
--- a/nio/src/main/java/java/nio/channels/Pipe.java
+++ b/nio/src/main/java/java/nio/channels/Pipe.java
@@ -25,13 +25,11 @@
* is the readable source channel. When bytes are written into the writable
* channel they can be read from the readable channel. The order of these bytes
* remains unchanged.
- * @since Android 1.0
*/
public abstract class Pipe {
/**
* Writable sink channel used to write to a pipe.
- * @since Android 1.0
*/
public static abstract class SinkChannel extends AbstractSelectableChannel
implements WritableByteChannel, GatheringByteChannel {
@@ -41,7 +39,6 @@
*
* @param provider
* the provider of the channel.
- * @since Android 1.0
*/
protected SinkChannel(SelectorProvider provider) {
super(provider);
@@ -51,8 +48,8 @@
* Indicates that this channel only supports writing.
*
* @return a static value of OP_WRITE.
- * @since Android 1.0
*/
+ @Override
public final int validOps() {
return SelectionKey.OP_WRITE;
}
@@ -60,7 +57,6 @@
/**
* Readable source channel used to read from a pipe.
- * @since Android 1.0
*/
public static abstract class SourceChannel extends
AbstractSelectableChannel implements ReadableByteChannel,
@@ -71,7 +67,6 @@
*
* @param provider
* the provider of the channel.
- * @since Android 1.0
*/
protected SourceChannel(SelectorProvider provider) {
super(provider);
@@ -81,8 +76,8 @@
* Indicates that this channel only supports reading.
*
* @return a static value of OP_READ.
- * @since Android 1.0
*/
+ @Override
public final int validOps() {
return SelectionKey.OP_READ;
}
@@ -96,7 +91,6 @@
*
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public static Pipe open() throws IOException {
return SelectorProvider.provider().openPipe();
@@ -104,8 +98,6 @@
/**
* The protected default constructor.
- *
- * @since Android 1.0
*/
protected Pipe() {
super();
@@ -115,7 +107,6 @@
* Returns the sink channel of the pipe.
*
* @return a writable sink channel of the pipe.
- * @since Android 1.0
*/
public abstract SinkChannel sink();
@@ -123,7 +114,6 @@
* Returns the source channel of the pipe.
*
* @return a readable source channel of the pipe.
- * @since Android 1.0
*/
public abstract SourceChannel source();
diff --git a/nio/src/main/java/java/nio/channels/ReadableByteChannel.java b/nio/src/main/java/java/nio/channels/ReadableByteChannel.java
index 9be1a72..649b64c 100644
--- a/nio/src/main/java/java/nio/channels/ReadableByteChannel.java
+++ b/nio/src/main/java/java/nio/channels/ReadableByteChannel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -28,9 +27,6 @@
* if a read is already in progress on the channel then subsequent reads will
* block until the first read completes. It is undefined whether non-read
* operations will block.
- * </p>
- *
- * @since Android 1.0
*/
public interface ReadableByteChannel extends Channel {
@@ -42,17 +38,14 @@
* buffer when the method is invoked. The bytes will be read into the buffer
* starting at the buffer's current
* {@link java.nio.Buffer#position() position}.
- * </p>
* <p>
* The call may block if other threads are also attempting to read from the
* same channel.
- * </p>
* <p>
* Upon completion, the buffer's {@code position} is updated to the end of
* the bytes that were read. The buffer's
* {@link java.nio.Buffer#limit() limit} is not changed.
- * </p>
- *
+ *
* @param buffer
* the byte buffer to receive the bytes.
* @return the number of bytes actually read.
@@ -60,7 +53,7 @@
* if another thread closes the channel during the read.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws ClosedChannelException
* if the channel is closed.
@@ -68,7 +61,6 @@
* another I/O error occurs, details are in the message.
* @throws NonReadableChannelException
* if the channel was not opened for reading.
- * @since Android 1.0
*/
public int read(ByteBuffer buffer) throws IOException;
}
diff --git a/nio/src/main/java/java/nio/channels/ScatteringByteChannel.java b/nio/src/main/java/java/nio/channels/ScatteringByteChannel.java
index 2e654db..d25f69c 100644
--- a/nio/src/main/java/java/nio/channels/ScatteringByteChannel.java
+++ b/nio/src/main/java/java/nio/channels/ScatteringByteChannel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -24,8 +23,6 @@
* The interface for channels that can read data into a set of buffers in a
* single operation. The corresponding interface for writes is
* {@link GatheringByteChannel}.
- *
- * @since Android 1.0
*/
public interface ScatteringByteChannel extends ReadableByteChannel {
@@ -33,8 +30,7 @@
* Reads bytes from this channel into the specified array of buffers.
* <p>
* This method is equivalent to {@code read(buffers, 0, buffers.length);}
- * </p>
- *
+ *
* @param buffers
* the array of byte buffers to store the bytes being read.
* @return the number of bytes actually read.
@@ -43,7 +39,7 @@
* operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws ClosedChannelException
* if the channel is closed.
@@ -52,21 +48,16 @@
* @throws NonWritableChannelException
* if the channel has not been opened in a mode that permits
* reading.
- * @since Android 1.0
*/
public long read(ByteBuffer[] buffers) throws IOException;
/**
- * Reads bytes from this channel and stores them in a subset of the
- * specified array of buffers. The subset is defined by {@code offset} and
- * {@code length}, indicating the first buffer and the number of buffers to
- * use. This method attempts to read as many bytes as can be stored in the
- * buffer subset from the channel and returns the number of bytes actually
- * read.
+ * Attempts to read all {@code remaining()} bytes from {@code length} byte
+ * buffers, in order, starting at {@code buffers[offset]}. The number of
+ * bytes actually read is returned.
* <p>
* If a read operation is in progress, subsequent threads will block until
* the read is completed and will then contend for the ability to read.
- * </p>
*
* @param buffers
* the array of byte buffers into which the bytes will be copied.
@@ -80,7 +71,7 @@
* operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
- * operation is in progress. The interrupt state of the calling
+ * operation is in progress. The interrupt state of the calling
* thread is set and the channel is closed.
* @throws ClosedChannelException
* if the channel is closed.
@@ -93,9 +84,7 @@
* @throws NonWritableChannelException
* if the channel has not been opened in a mode that permits
* reading.
- * @since Android 1.0
*/
public long read(ByteBuffer[] buffers, int offset, int length)
throws IOException;
-
}
diff --git a/nio/src/main/java/java/nio/channels/SelectableChannel.java b/nio/src/main/java/java/nio/channels/SelectableChannel.java
index ded66e6..6ac9a51 100644
--- a/nio/src/main/java/java/nio/channels/SelectableChannel.java
+++ b/nio/src/main/java/java/nio/channels/SelectableChannel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
import java.nio.channels.spi.AbstractInterruptibleChannel;
import java.nio.channels.spi.SelectorProvider;
@@ -31,16 +30,12 @@
* <p>
* A channel may be registered with several selectors at the same time but only
* once for any given selector.
- * </p>
- * @since Android 1.0
*/
public abstract class SelectableChannel extends AbstractInterruptibleChannel
implements Channel {
/**
* Constructs a new {@code SelectableChannel}.
- *
- * @since Android 1.0
*/
protected SelectableChannel() {
super();
@@ -51,7 +46,6 @@
* and {@code register} methods.
*
* @return the blocking object as lock.
- * @since Android 1.0
*/
public abstract Object blockingLock();
@@ -74,7 +68,6 @@
* registered with at least one selector.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract SelectableChannel configureBlocking(boolean block)
throws IOException;
@@ -84,7 +77,6 @@
*
* @return {@code true} if this channel is blocking, undefined if this
* channel is closed.
- * @since Android 1.0
*/
public abstract boolean isBlocking();
@@ -93,7 +85,6 @@
*
* @return {@code true} if this channel is registered, {@code false}
* otherwise.
- * @since Android 1.0
*/
public abstract boolean isRegistered();
@@ -104,7 +95,6 @@
* the selector with which this channel has been registered.
* @return the selection key for the channel or {@code null} if this channel
* has not been registered with {@code sel}.
- * @since Android 1.0
*/
public abstract SelectionKey keyFor(Selector sel);
@@ -112,7 +102,6 @@
* Gets the provider of this channel.
*
* @return the provider of this channel.
- * @since Android 1.0
*/
public abstract SelectorProvider provider();
@@ -129,12 +118,10 @@
* blocked until the other call finishes. After that, it will synchronize on
* the key set of the selector and thus may again block if other threads
* also hold locks on the key set of the same selector.
- * </p>
* <p>
* Calling this method is equivalent to calling
* {@code register(selector, operations, null)}.
- * </p>
- *
+ *
* @param selector
* the selector with which to register this channel.
* @param operations
@@ -151,7 +138,6 @@
* if this channel is registered but its key has been canceled.
* @throws IllegalArgumentException
* if the operation given is not supported by this channel.
- * @since Android 1.0
*/
public final SelectionKey register(Selector selector, int operations)
throws ClosedChannelException {
@@ -171,8 +157,7 @@
* blocked until the other call finishes. After that, it will synchronize on
* the key set of the selector and thus may again block if other threads
* also hold locks on the key set of the same selector.
- * </p>
- *
+ *
* @param sel
* the selector with which to register this channel.
* @param ops
@@ -191,18 +176,15 @@
* selector.
* @throws CancelledKeyException
* if this channel is registered but its key has been canceled.
- * @since Android 1.0
*/
public abstract SelectionKey register(Selector sel, int ops, Object att)
throws ClosedChannelException;
/**
* Gets the set of valid {@link SelectionKey operations} of this channel.
- * Instances of a concrete channel class always return the same value.
- *
+ * Instances of a concrete channel class always return the same value.
+ *
* @return the set of operations that this channel supports.
- * @since Android 1.0
*/
public abstract int validOps();
-
}
diff --git a/nio/src/main/java/java/nio/channels/SelectionKey.java b/nio/src/main/java/java/nio/channels/SelectionKey.java
index b3773fa..d00627e 100644
--- a/nio/src/main/java/java/nio/channels/SelectionKey.java
+++ b/nio/src/main/java/java/nio/channels/SelectionKey.java
@@ -32,36 +32,26 @@
* <h4>Ready set</h4>
* The ready set is an operation set that shows the operations that a
* {@code channel} is ready to execute.
- *
- * @since Android 1.0
*/
public abstract class SelectionKey {
/**
* Interest set mask bit for socket-accept operations.
- *
- * @since Android 1.0
*/
public static final int OP_ACCEPT = 16;
/**
* Interest set mask bit for socket-connect operations.
- *
- * @since Android 1.0
*/
public static final int OP_CONNECT = 8;
/**
* Interesting operation mask bit for read operations.
- *
- * @since Android 1.0
*/
public static final int OP_READ = 1;
/**
* Interest set mask bit for write operations.
- *
- * @since Android 1.0
*/
public static final int OP_WRITE = 4;
@@ -69,8 +59,6 @@
/**
* Constructs a new {@code SelectionKey}.
- *
- * @since Android 1.0
*/
protected SelectionKey() {
super();
@@ -85,7 +73,6 @@
* attachment.
* @return the last attached object or {@code null} if no object has been
* attached.
- * @since Android 1.0
*/
public final Object attach(Object anObject) {
Object oldAttachment = attachment;
@@ -98,7 +85,6 @@
*
* @return the attached object or {@code null} if no object has been
* attached.
- * @since Android 1.0
*/
public final Object attachment() {
return attachment;
@@ -109,7 +95,6 @@
* <p>
* A key that has been canceled is no longer valid. Calling this method on
* an already canceled key does nothing.
- * </p>
* <p>
* Calling this method is safe at any time. The call might block until
* another ongoing call to a method of this selector has finished. The
@@ -117,9 +102,6 @@
* this call finishes, the key will have been added to the selectors
* canceled-keys set and will not be included in any future selects of this
* selector.
- * </p>
- *
- * @since Android 1.0
*/
public abstract void cancel();
@@ -127,7 +109,6 @@
* Gets the channel of this key.
*
* @return the channel of this key.
- * @since Android 1.0
*/
public abstract SelectableChannel channel();
@@ -138,7 +119,6 @@
* @return the interest set of this key.
* @throws CancelledKeyException
* if the key has already been canceled.
- * @since Android 1.0
*/
public abstract int interestOps();
@@ -154,7 +134,6 @@
* key's channel.
* @throws CancelledKeyException
* if the key has already been canceled.
- * @since Android 1.0
*/
public abstract SelectionKey interestOps(int operations);
@@ -167,7 +146,6 @@
* and is ready to accept new connections, {@code false} otherwise.
* @throws CancelledKeyException
* if the key has already been canceled.
- * @since Android 1.0
*/
public final boolean isAcceptable() {
return (readyOps() & OP_ACCEPT) == OP_ACCEPT;
@@ -182,8 +160,7 @@
* operation and is ready to connect, {@code false} otherwise.
* @throws CancelledKeyException
* if the key has already been canceled.
- * @since Android 1.0
- */
+ */
public final boolean isConnectable() {
return (readyOps() & OP_CONNECT) == OP_CONNECT;
}
@@ -197,7 +174,6 @@
* and is ready to read, {@code false} otherwise.
* @throws CancelledKeyException
* if the key has already been canceled.
- * @since Android 1.0
*/
public final boolean isReadable() {
return (readyOps() & OP_READ) == OP_READ;
@@ -209,7 +185,6 @@
*
* @return {@code true} if this key has not been canceled, {@code false}
* otherwise.
- * @since Android 1.0
*/
public abstract boolean isValid();
@@ -222,7 +197,6 @@
* and is ready to write, {@code false} otherwise.
* @throws CancelledKeyException
* if the key has already been canceled.
- * @since Android 1.0
*/
public final boolean isWritable() {
return (readyOps() & OP_WRITE) == OP_WRITE;
@@ -235,7 +209,6 @@
* @return the operations for which this key's channel is ready.
* @throws CancelledKeyException
* if the key has already been canceled.
- * @since Android 1.0
*/
public abstract int readyOps();
@@ -243,7 +216,6 @@
* Gets the selector for which this key's channel is registered.
*
* @return the related selector.
- * @since Android 1.0
*/
public abstract Selector selector();
}
diff --git a/nio/src/main/java/java/nio/channels/Selector.java b/nio/src/main/java/java/nio/channels/Selector.java
index d417f51..8d43f4b 100644
--- a/nio/src/main/java/java/nio/channels/Selector.java
+++ b/nio/src/main/java/java/nio/channels/Selector.java
@@ -32,9 +32,6 @@
* canceled keys. During the select operation, the channels registered with this
* selector are checked to see whether they are ready for operation according to
* their {@link SelectionKey interest set}.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class Selector {
@@ -46,7 +43,6 @@
* @return a new selector.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public static Selector open() throws IOException {
return SelectorProvider.provider().openSelector();
@@ -54,8 +50,6 @@
/**
* Constructs a new {@code Selector}.
- *
- * @since Android 1.0
*/
protected Selector() {
super();
@@ -71,11 +65,9 @@
* Any further attempt of using this selector after this method has been
* called (except calling {@link #close()} or {@link #wakeup()}) results in
* a {@link ClosedSelectorException} being thrown.
- * </p>
- *
+ *
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract void close() throws IOException;
@@ -84,7 +76,6 @@
*
* @return {@code true} if this selector is not closed, {@code false}
* otherwise.
- * @since Android 1.0
*/
public abstract boolean isOpen();
@@ -93,7 +84,6 @@
* safe.
*
* @return the set of registered keys.
- * @since Android 1.0
*/
public abstract Set<SelectionKey> keys();
@@ -101,7 +91,6 @@
* Gets the provider of this selector.
*
* @return the provider of this selector.
- * @since Android 1.0
*/
public abstract SelectorProvider provider();
@@ -116,7 +105,6 @@
* if an I/O error occurs.
* @throws ClosedSelectorException
* if the selector is closed.
- * @since Android 1.0
*/
public abstract int select() throws IOException;
@@ -137,7 +125,6 @@
* if the given timeout argument is less than zero.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract int select(long timeout) throws IOException;
@@ -149,7 +136,6 @@
* @return the selection keys whose channels are ready for operation.
* @throws ClosedSelectorException
* if the selector is closed.
- * @since Android 1.0
*/
public abstract Set<SelectionKey> selectedKeys();
@@ -164,7 +150,6 @@
* if an I/O error occurrs.
* @throws ClosedSelectorException
* if the selector is closed.
- * @since Android 1.0
*/
public abstract int selectNow() throws IOException;
@@ -176,12 +161,10 @@
* be undone by a call to {@code selectNow()}; after calling
* {@code selectNow()}, a subsequent call of {@code select} can block
* again.
- * </p>
- *
+ *
* @return this selector.
* @throws ClosedSelectorException
* if the selector is closed.
- * @since Android 1.0
*/
public abstract Selector wakeup();
}
diff --git a/nio/src/main/java/java/nio/channels/ServerSocketChannel.java b/nio/src/main/java/java/nio/channels/ServerSocketChannel.java
index 8ecb183..b0508fa 100644
--- a/nio/src/main/java/java/nio/channels/ServerSocketChannel.java
+++ b/nio/src/main/java/java/nio/channels/ServerSocketChannel.java
@@ -33,9 +33,6 @@
* open()} method. Calling {@code accept} before bound will cause a
* {@link NotYetBoundException}. It can be bound by calling the bind method of a
* related {@code ServerSocket} instance.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class ServerSocketChannel extends AbstractSelectableChannel {
@@ -44,7 +41,6 @@
*
* @param selectorProvider
* an instance of SelectorProvider.
- * @since Android 1.0
*/
protected ServerSocketChannel(SelectorProvider selectorProvider) {
super(selectorProvider);
@@ -55,12 +51,10 @@
* <p>
* This channel is created by calling {@code openServerSocketChannel} method
* of the default {@code SelectorProvider} instance.
- * </p>
- *
+ *
* @return the new channel which is open but unbound.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public static ServerSocketChannel open() throws IOException {
return SelectorProvider.provider().openServerSocketChannel();
@@ -73,8 +67,8 @@
*
* @see java.nio.channels.SelectableChannel#validOps()
* @return the operations supported by this channel.
- * @since Android 1.0
*/
+ @Override
public final int validOps() {
return SelectionKey.OP_ACCEPT;
}
@@ -84,7 +78,6 @@
* any public methods that are not declared in {@code ServerSocket}.
*
* @return the server-socket assigned to this channel.
- * @since Android 1.0
*/
public abstract ServerSocket socket();
@@ -95,11 +88,9 @@
* connection is available, otherwise it blocks until a new connection is
* available or an I/O error occurs. The socket channel returned by this
* method will always be in blocking mode.
- * </p>
* <p>
* This method just executes the same security checks as the {@code
* accept()} method of the {@link ServerSocket} class.
- * </p>
*
* @return the accepted {@code SocketChannel} instance, or {@code null} if
* the channel is non-blocking and no connection is available.
@@ -119,8 +110,6 @@
* @throws SecurityException
* if there is a security manager and it does not permit to
* access the new connection.
- * @since Android 1.0
*/
public abstract SocketChannel accept() throws IOException;
-
}
diff --git a/nio/src/main/java/java/nio/channels/SocketChannel.java b/nio/src/main/java/java/nio/channels/SocketChannel.java
index a709dee..40003ea 100644
--- a/nio/src/main/java/java/nio/channels/SocketChannel.java
+++ b/nio/src/main/java/java/nio/channels/SocketChannel.java
@@ -39,7 +39,6 @@
* connecting. {@code isConnectionPending()} indicates if the connection is
* blocked or not; {@code isConnected()} indicates if the socket is finally
* connected or not.
- * </p>
* <p>
* The input and output sides of a channel can be shut down independently and
* asynchronously without closing the channel. The {@code shutdownInput} method
@@ -51,15 +50,11 @@
* {@link ClosedChannelException}. If the output is shut down and another thread
* is blocked in a write operation, an {@link AsynchronousCloseException} will
* be thrown to the pending thread.
- * </p>
* <p>
* Socket channels are thread-safe, no more than one thread can read or write at
* any given time. The {@code connect(SocketAddress)} and {@code
* finishConnect()} methods are synchronized against each other; when they are
* processing, calls to {@code read} and {@code write} will block.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class SocketChannel extends AbstractSelectableChannel implements
ByteChannel, ScatteringByteChannel, GatheringByteChannel {
@@ -67,13 +62,12 @@
static {
Platform.getNetworkSystem().oneTimeInitialization(true);
}
-
+
/**
* Constructs a new {@code SocketChannel}.
*
* @param selectorProvider
* an instance of SelectorProvider.
- * @since Android 1.0
*/
protected SocketChannel(SelectorProvider selectorProvider) {
super(selectorProvider);
@@ -84,12 +78,10 @@
* <p>
* This channel is created by calling {@code openSocketChannel()} of the
* default {@link SelectorProvider} instance.
- * </p>
- *
+ *
* @return the new channel which is open but unconnected.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public static SocketChannel open() throws IOException {
return SelectorProvider.provider().openSocketChannel();
@@ -100,8 +92,7 @@
* <p>
* This method performs a call to {@code open()} followed by a call to
* {@code connect(SocketAdress)}.
- * </p>
- *
+ *
* @param address
* the socket address to be connected to.
* @return the new connected channel.
@@ -121,7 +112,6 @@
* if the address type is not supported.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public static SocketChannel open(SocketAddress address) throws IOException {
SocketChannel socketChannel = open();
@@ -138,8 +128,8 @@
*
* @return the operations supported by this channel.
* @see java.nio.channels.SelectableChannel#validOps()
- * @since Android 1.0
*/
+ @Override
public final int validOps() {
return (SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
@@ -149,7 +139,6 @@
* methods that are not declared in {@code Socket}.
*
* @return the socket assigned to this channel.
- * @since Android 1.0
*/
public abstract Socket socket();
@@ -158,7 +147,6 @@
*
* @return {@code true} if this channel's socket is connected, {@code false}
* otherwise.
- * @since Android 1.0
*/
public abstract boolean isConnected();
@@ -167,7 +155,6 @@
*
* @return {@code true} if the connection is initiated but not finished;
* {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean isConnectionPending();
@@ -179,13 +166,11 @@
* this method will return {@code true} if the connection is finished at
* once or return {@code false} when the connection must be finished later
* by calling {@code finishConnect()}.
- * </p>
* <p>
* This method can be called at any moment and can block other read and
* write operations while connecting. It executes the same security checks
* as the connect method of the {@code Socket} class.
- * </p>
- *
+ *
* @param address
* the address to connect with.
* @return {@code true} if the connection is finished, {@code false}
@@ -213,7 +198,6 @@
* {@code address}.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract boolean connect(SocketAddress address) throws IOException;
@@ -224,17 +208,14 @@
* This method returns {@code true} if the connection is finished already
* and returns {@code false} if the channel is non-blocking and the
* connection is not finished yet.
- * </p>
* <p>
* If this channel is in blocking mode, this method will suspend and return
* {@code true} when the connection is finished. It closes this channel and
* throws an exception if the connection fails.
- * </p>
* <p>
* This method can be called at any moment and it can block other {@code
* read} and {@code write} operations while connecting.
- * </p>
- *
+ *
* @return {@code true} if the connection is successfully finished, {@code
* false} otherwise.
* @throws NoConnectionPendingException
@@ -251,7 +232,6 @@
* interrupt state set, and this channel is closed.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract boolean finishConnect() throws IOException;
@@ -261,16 +241,13 @@
* The maximum number of bytes that will be read is the remaining number of
* bytes in the buffer when the method is invoked. The bytes will be copied
* into the buffer starting at the buffer's current position.
- * </p>
* <p>
* The call may block if other threads are also attempting to read from this
* channel.
- * </p>
* <p>
* Upon completion, the buffer's position is set to the end of the bytes
* that have been read. The buffer's limit is not changed.
- * </p>
- *
+ *
* @param target
* the byte buffer to receive the bytes.
* @return the number of bytes actually read.
@@ -286,22 +263,19 @@
* if this channel is closed.
* @throws IOException
* if another I/O error occurs.
- * @since Android 1.0
+ * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
*/
public abstract int read(ByteBuffer target) throws IOException;
/**
- * Reads bytes from this socket channel and stores them in a subset of the
- * specified array of buffers. The subset is defined by {@code offset} and
- * {@code length}, indicating the first buffer and the number of buffers to
- * use. This method attempts to read as many bytes as can be stored in the
- * buffer subset from this channel and returns the number of bytes actually
- * read.
+ * Reads bytes from this socket channel into a subset of the given buffers.
+ * This method attempts to read all {@code remaining()} bytes from {@code
+ * length} byte buffers, in order, starting at {@code targets[offset]}. The
+ * number of bytes actually read is returned.
* <p>
* If a read operation is in progress, subsequent threads will block until
* the read is completed and will then contend for the ability to read.
- * </p>
- *
+ *
* @param targets
* the array of byte buffers into which the bytes will be copied.
* @param offset
@@ -325,7 +299,8 @@
* if another I/O error occurs.
* @throws NotYetConnectedException
* if this channel is not yet connected.
- * @since Android 1.0
+ * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
+ * int, int)
*/
public abstract long read(ByteBuffer[] targets, int offset, int length)
throws IOException;
@@ -338,12 +313,10 @@
* <p>
* If a read operation is in progress, subsequent threads will block until
* the read is completed and will then contend for the ability to read.
- * </p>
* <p>
* Calling this method is equivalent to calling {@code read(targets, 0,
* targets.length);}
- * </p>
- *
+ *
* @param targets
* the array of byte buffers into which the bytes will be copied.
* @return the number of bytes actually read.
@@ -360,7 +333,6 @@
* if another I/O error occurs.
* @throws NotYetConnectedException
* if this channel is not yet connected.
- * @since Android 1.0
*/
public synchronized final long read(ByteBuffer[] targets)
throws IOException {
@@ -375,12 +347,10 @@
* <p>
* The call may block if other threads are also attempting to write to the
* same channel.
- * </p>
* <p>
* Upon completion, the buffer's position is updated to the end of the bytes
* that have been written. The buffer's limit is not changed.
- * </p>
- *
+ *
* @param source
* the byte buffer containing the bytes to be written.
* @return the number of bytes actually written.
@@ -396,19 +366,19 @@
* if another I/O error occurs.
* @throws NotYetConnectedException
* if this channel is not connected yet.
- * @since Android 1.0
+ * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
*/
public abstract int write(ByteBuffer source) throws IOException;
/**
- * Writes bytes from a subset of the specified array of buffers into this
- * socket channel. The subset is defined by {@code offset} and {@code
- * length}, indicating the first buffer and the number of buffers to use.
+ * Attempts to write a subset of the given bytes from the buffers to this
+ * socket channel. This method attempts to write all {@code remaining()}
+ * bytes from {@code length} byte buffers, in order, starting at {@code
+ * sources[offset]}. The number of bytes actually written is returned.
* <p>
* If a write operation is in progress, subsequent threads will block until
* the write is completed and then contend for the ability to write.
- * </p>
- *
+ *
* @param sources
* the array of byte buffers that is the source for bytes written
* to this channel.
@@ -434,7 +404,8 @@
* if another I/O error occurs.
* @throws NotYetConnectedException
* if this channel is not yet connected.
- * @since Android 1.0
+ * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
+ * int, int)
*/
public abstract long write(ByteBuffer[] sources, int offset, int length)
throws IOException;
@@ -444,8 +415,7 @@
* <p>
* Calling this method is equivalent to calling {@code write(sources, 0,
* sources.length);}
- * </p>
- *
+ *
* @param sources
* the buffers containing bytes to write.
* @return the number of bytes actually written.
@@ -462,7 +432,7 @@
* if another I/O error occurs.
* @throws NotYetConnectedException
* if this channel is not yet connected.
- * @since Android 1.0
+ * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
*/
public synchronized final long write(ByteBuffer[] sources)
throws IOException {
diff --git a/nio/src/main/java/java/nio/channels/UnresolvedAddressException.java b/nio/src/main/java/java/nio/channels/UnresolvedAddressException.java
index dfb475b..426e84c 100644
--- a/nio/src/main/java/java/nio/channels/UnresolvedAddressException.java
+++ b/nio/src/main/java/java/nio/channels/UnresolvedAddressException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* An {@code UnresolvedAddressException} is thrown when trying to use an
* unresolved network address in a network operation.
- *
- * @since Android 1.0
*/
public class UnresolvedAddressException extends IllegalArgumentException {
@@ -29,8 +26,6 @@
/**
* Constructs an {@code UnresolvedAddressException}.
- *
- * @since Android 1.0
*/
public UnresolvedAddressException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/UnsupportedAddressTypeException.java b/nio/src/main/java/java/nio/channels/UnsupportedAddressTypeException.java
index ba613ac..62c1515 100644
--- a/nio/src/main/java/java/nio/channels/UnsupportedAddressTypeException.java
+++ b/nio/src/main/java/java/nio/channels/UnsupportedAddressTypeException.java
@@ -16,12 +16,9 @@
package java.nio.channels;
-
/**
* An {@code UnsupportedAddressTypeException} is thrown when connecting or
* binding to an unsupported address type.
- *
- * @since Android 1.0
*/
public class UnsupportedAddressTypeException extends IllegalArgumentException {
@@ -29,8 +26,6 @@
/**
* Constructs an {@code UnsupportedAddressTypeException}.
- *
- * @since Android 1.0
*/
public UnsupportedAddressTypeException() {
super();
diff --git a/nio/src/main/java/java/nio/channels/WritableByteChannel.java b/nio/src/main/java/java/nio/channels/WritableByteChannel.java
index f8ea77f..4a9779a 100644
--- a/nio/src/main/java/java/nio/channels/WritableByteChannel.java
+++ b/nio/src/main/java/java/nio/channels/WritableByteChannel.java
@@ -16,7 +16,6 @@
package java.nio.channels;
-
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -28,8 +27,6 @@
* if a write is already in progress on the channel then subsequent writes will
* block until the first write completes. It is undefined whether non-write
* operations will block.
- *
- * @since Android 1.0
*/
public interface WritableByteChannel extends Channel {
@@ -40,17 +37,14 @@
* <code>remaining()</code> number of bytes in the buffer when the method
* invoked. The bytes will be written from the buffer starting at the
* buffer's <code>position</code>.
- * </p>
* <p>
* The call may block if other threads are also attempting to write on the
* same channel.
- * </p>
* <p>
* Upon completion, the buffer's <code>position()</code> is updated to the
* end of the bytes that were written. The buffer's <code>limit()</code>
* is unmodified.
- * </p>
- *
+ *
* @param buffer
* the byte buffer containing the bytes to be written.
* @return the number of bytes actually written.
@@ -65,7 +59,6 @@
* write.
* @throws IOException
* another IO exception occurs, details are in the message.
- * @since Android 1.0
*/
public int write(ByteBuffer buffer) throws IOException;
}
diff --git a/nio/src/main/java/java/nio/channels/spi/AbstractInterruptibleChannel.java b/nio/src/main/java/java/nio/channels/spi/AbstractInterruptibleChannel.java
index 8f84e109..878f731 100644
--- a/nio/src/main/java/java/nio/channels/spi/AbstractInterruptibleChannel.java
+++ b/nio/src/main/java/java/nio/channels/spi/AbstractInterruptibleChannel.java
@@ -24,6 +24,7 @@
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.InterruptibleChannel;
import java.security.AccessController;
+import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
/**
@@ -35,10 +36,7 @@
* indefinitely, then {@code end(boolean)} after completing the operation. The
* argument to the {@code end} method should indicate if the I/O operation has
* actually completed so that any change may be visible to the invoker.
- * </p>
- *
- * @since Android 1.0
- */
+*/
public abstract class AbstractInterruptibleChannel implements Channel,
InterruptibleChannel {
@@ -56,7 +54,7 @@
}
});
setInterruptAction.setAccessible(true);
- } catch (Exception e) {
+ } catch (PrivilegedActionException e) {
// FIXME: be accommodate before VM actually provides
// setInterruptAction method
// throw new Error(e);
@@ -69,8 +67,6 @@
/**
* Default constructor.
- *
- * @since Android 1.0
*/
protected AbstractInterruptibleChannel() {
super();
@@ -82,7 +78,6 @@
* @return {@code true} if this channel is open, {@code false} if it is
* closed.
* @see java.nio.channels.Channel#isOpen()
- * @since Android 1.0
*/
public synchronized final boolean isOpen() {
return !closed;
@@ -95,16 +90,14 @@
* <p>
* If an attempt is made to perform an operation on a closed channel then a
* {@link java.nio.channels.ClosedChannelException} is thrown.
- * </p>
* <p>
* If multiple threads attempt to simultaneously close a channel, then only
* one thread will run the closure code and the others will be blocked until
* the first one completes.
- * </p>
- *
+ *
* @throws IOException
* if a problem occurs while closing this channel.
- * @since Android 1.0
+ * @see java.nio.channels.Channel#close()
*/
public final void close() throws IOException {
if (!closed) {
@@ -121,8 +114,6 @@
* Indicates the beginning of a code section that includes an I/O operation
* that is potentially blocking. After this operation, the application
* should invoke the corresponding {@code end(boolean)} method.
- *
- * @since Android 1.0
*/
protected final void begin() {
// FIXME: be accommodate before VM actually provides
@@ -159,7 +150,6 @@
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while this
* method is executing.
- * @since Android 1.0
*/
protected final void end(boolean success) throws AsynchronousCloseException {
// FIXME: be accommodate before VM actually provides
@@ -187,16 +177,13 @@
* Closes the channel with a guarantee that the channel is not currently
* closed through another invocation of {@code close()} and that the method
* is thread-safe.
- * </p>
* <p>
* Any outstanding threads blocked on I/O operations on this channel must be
* released with either a normal return code, or by throwing an
* {@code AsynchronousCloseException}.
- * </p>
*
* @throws IOException
* if a problem occurs while closing the channel.
- * @since Android 1.0
*/
protected abstract void implCloseChannel() throws IOException;
}
diff --git a/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java b/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java
index a9bee52..54092ed 100644
--- a/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java
+++ b/nio/src/main/java/java/nio/channels/spi/AbstractSelectableChannel.java
@@ -32,8 +32,6 @@
* {@code AbstractSelectableChannel} is the base implementation class for
* selectable channels. It declares methods for registering, unregistering and
* closing selectable channels. It is thread-safe.
- *
- * @since Android 1.0
*/
public abstract class AbstractSelectableChannel extends SelectableChannel {
@@ -44,7 +42,8 @@
*/
private List<SelectionKey> keyList = new ArrayList<SelectionKey>();
- private class BlockingLock {
+ // Marker class so lock type shows up in profilers
+ static private class BlockingLock {
}
private final Object blockingLock = new BlockingLock();
@@ -56,7 +55,6 @@
*
* @param selectorProvider
* the selector provider that creates this channel.
- * @since Android 1.0
*/
protected AbstractSelectableChannel(SelectorProvider selectorProvider) {
super();
@@ -68,32 +66,32 @@
*
* @see java.nio.channels.SelectableChannel#provider()
* @return this channel's selector provider.
- * @since Android 1.0
*/
+ @Override
public final SelectorProvider provider() {
return provider;
}
/**
* Indicates whether this channel is registered with one or more selectors.
- *
+ *
* @return {@code true} if this channel is registered with a selector,
* {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
synchronized public final boolean isRegistered() {
return !keyList.isEmpty();
}
/**
* Gets this channel's selection key for the specified selector.
- *
+ *
* @param selector
* the selector with which this channel has been registered.
* @return the selection key for the channel or {@code null} if this channel
* has not been registered with {@code selector}.
- * @since Android 1.0
*/
+ @Override
synchronized public final SelectionKey keyFor(Selector selector) {
for (int i = 0; i < keyList.size(); i++) {
SelectionKey key = keyList.get(i);
@@ -130,8 +128,8 @@
* @throws IllegalSelectorException
* if this channel does not have the same provider as the given
* selector.
- * @since Android 1.0
*/
+ @Override
public final SelectionKey register(Selector selector, int interestSet,
Object attachment) throws ClosedChannelException {
if (!isOpen()) {
@@ -153,10 +151,6 @@
// throw NPE exactly to keep consistency
throw new NullPointerException();
}
- if (0 == interestSet) {
- // throw ISE exactly to keep consistency
- throw new IllegalSelectorException();
- }
SelectionKey key = keyFor(selector);
if (null == key) {
key = ((AbstractSelector) selector).register(this, interestSet,
@@ -181,8 +175,8 @@
*
* @throws IOException
* if a problem occurs while closing the channel.
- * @since Android 1.0
*/
+ @Override
synchronized protected final void implCloseChannel() throws IOException {
implCloseSelectableChannel();
for (int i = 0; i < keyList.size(); i++) {
@@ -199,17 +193,16 @@
*
* @throws IOException
* if an I/O exception occurs.
- * @since Android 1.0
*/
protected abstract void implCloseSelectableChannel() throws IOException;
/**
* Indicates whether this channel is in blocking mode.
- *
+ *
* @return {@code true} if this channel is blocking, {@code false}
* otherwise.
- * @since Android 1.0
*/
+ @Override
public final boolean isBlocking() {
synchronized (blockingLock) {
return isBlocking;
@@ -219,10 +212,10 @@
/**
* Gets the object used for the synchronization of {@code register} and
* {@code configureBlocking}.
- *
+ *
* @return the synchronization object.
- * @since Android 1.0
*/
+ @Override
public final Object blockingLock() {
return blockingLock;
}
@@ -233,6 +226,7 @@
* actual setting of the mode is done by calling
* {@code implConfigureBlocking(boolean)}.
*
+ * @see java.nio.channels.SelectableChannel#configureBlocking(boolean)
* @param blockingMode
* {@code true} for setting this channel's mode to blocking,
* {@code false} to set it to non-blocking.
@@ -244,8 +238,8 @@
* registered with at least one selector.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
+ @Override
public final SelectableChannel configureBlocking(boolean blockingMode)
throws IOException {
if (isOpen()) {
@@ -253,7 +247,7 @@
if (isBlocking == blockingMode) {
return this;
}
- if (blockingMode && isRegistered()) {
+ if (blockingMode && containsValidKeys()) {
throw new IllegalBlockingModeException();
}
implConfigureBlocking(blockingMode);
@@ -262,7 +256,6 @@
return this;
}
throw new ClosedChannelException();
-
}
/**
@@ -273,7 +266,6 @@
* {@code false} to set it to non-blocking.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
protected abstract void implConfigureBlocking(boolean blockingMode)
throws IOException;
@@ -287,4 +279,17 @@
}
}
+ /**
+ * Returns true if the keyList contains at least 1 valid key and false
+ * otherwise.
+ */
+ private synchronized boolean containsValidKeys() {
+ for (int i = 0; i < keyList.size(); i++) {
+ SelectionKey key = keyList.get(i);
+ if (key != null && key.isValid()) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/nio/src/main/java/java/nio/channels/spi/AbstractSelectionKey.java b/nio/src/main/java/java/nio/channels/spi/AbstractSelectionKey.java
index e839126..4c46226 100644
--- a/nio/src/main/java/java/nio/channels/spi/AbstractSelectionKey.java
+++ b/nio/src/main/java/java/nio/channels/spi/AbstractSelectionKey.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+
package java.nio.channels.spi;
import java.nio.channels.SelectionKey;
@@ -21,8 +21,6 @@
/**
* {@code AbstractSelectionKey} is the base implementation class for selection keys.
* It implements validation and cancellation methods.
- *
- * @since Android 1.0
*/
public abstract class AbstractSelectionKey extends SelectionKey {
@@ -33,8 +31,6 @@
/**
* Constructs a new {@code AbstractSelectionKey}.
- *
- * @since Android 1.0
*/
protected AbstractSelectionKey() {
super();
@@ -43,11 +39,11 @@
/**
* Indicates whether this key is valid. A key is valid as long as it has not
* been canceled.
- *
+ *
* @return {@code true} if this key has not been canceled, {@code false}
* otherwise.
- * @since Android 1.0
*/
+ @Override
public final boolean isValid() {
return isValid;
}
@@ -57,10 +53,8 @@
* <p>
* A key that has been canceled is no longer valid. Calling this method on
* an already canceled key does nothing.
- * </p>
- *
- * @since Android 1.0
*/
+ @Override
public final void cancel() {
if (isValid) {
isValid = false;
diff --git a/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java b/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java
index adef243..26bbb4f 100644
--- a/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java
+++ b/nio/src/main/java/java/nio/channels/spi/AbstractSelector.java
@@ -22,17 +22,16 @@
import java.nio.channels.Selector;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* {@code AbstractSelector} is the base implementation class for selectors.
* It realizes the interruption of selection by {@code begin} and
* {@code end}. It also holds the cancellation and the deletion of the key
* set.
- *
- * @since Android 1.0
*/
public abstract class AbstractSelector extends Selector {
- private volatile boolean isOpen = true;
+ private final AtomicBoolean isOpen = new AtomicBoolean(true);
private SelectorProvider provider = null;
@@ -46,7 +45,6 @@
*
* @param selectorProvider
* the selector provider that creates this selector.
- * @since Android 1.0
*/
protected AbstractSelector(SelectorProvider selectorProvider) {
provider = selectorProvider;
@@ -59,11 +57,10 @@
*
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
- public synchronized final void close() throws IOException {
- if (isOpen) {
- isOpen = false;
+ @Override
+ public final void close() throws IOException {
+ if (isOpen.getAndSet(false)) {
implCloseSelector();
}
}
@@ -73,27 +70,26 @@
*
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
protected abstract void implCloseSelector() throws IOException;
/**
* Indicates whether this selector is open.
- *
+ *
* @return {@code true} if this selector is not closed, {@code false}
* otherwise.
- * @since Android 1.0
*/
+ @Override
public final boolean isOpen() {
- return isOpen;
+ return isOpen.get();
}
/**
* Gets this selector's provider.
*
* @return the provider of this selector.
- * @since Android 1.0
*/
+ @Override
public final SelectorProvider provider() {
return provider;
}
@@ -102,7 +98,6 @@
* Returns this channel's set of canceled selection keys.
*
* @return the set of canceled selection keys.
- * @since Android 1.0
*/
protected final Set<SelectionKey> cancelledKeys() {
return cancelledKeysSet;
@@ -118,7 +113,6 @@
* @param attachment
* the attachment for the selection key.
* @return the key related to the channel and this selector.
- * @since Android 1.0
*/
protected abstract SelectionKey register(AbstractSelectableChannel channel,
int operations, Object attachment);
@@ -128,7 +122,6 @@
*
* @param key
* the key.
- * @since Android 1.0
*/
protected final void deregister(AbstractSelectionKey key) {
((AbstractSelectableChannel) key.channel()).deregister(key);
@@ -139,8 +132,6 @@
* Indicates the beginning of a code section that includes an I/O operation
* that is potentially blocking. After this operation, the application
* should invoke the corresponding {@code end(boolean)} method.
- *
- * @since Android 1.0
*/
protected final void begin() {
// FIXME: be accommodate before VM actually provides
@@ -162,8 +153,6 @@
/**
* Indicates the end of a code section that has been started with
* {@code begin()} and that includes a potentially blocking I/O operation.
- *
- * @since Android 1.0
*/
protected final void end() {
// FIXME: be accommodate before VM actually provides
diff --git a/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java b/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
index b4b18e3..b474afa 100644
--- a/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
+++ b/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
@@ -42,9 +42,6 @@
* A provider instance can be retrieved through a system property or the
* configuration file in a jar file; if no provide is available that way then
* the system default provider is returned.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class SelectorProvider extends Object {
@@ -55,8 +52,8 @@
private static final String PROVIDER_IN_JAR_RESOURCE = "META-INF/services/java.nio.channels.spi.SelectorProvider"; //$NON-NLS-1$
private static SelectorProvider provider = null;
-
- private static Channel inheritedChannel;
+
+ private static Channel inheritedChannel;
/**
* Constructs a new {@code SelectorProvider}.
@@ -64,7 +61,6 @@
* @throws SecurityException
* if there is a security manager installed that does not permit
* the runtime permission labeled "selectorProvider".
- * @since Android 1.0
*/
protected SelectorProvider() {
super();
@@ -87,9 +83,8 @@
* provider's class name; </li>
* <li> otherwise, a system default provider will be returned.</li>
* </ul>
- *
+ *
* @return the provider.
- * @since Android 1.0
*/
synchronized public static SelectorProvider provider() {
if (null == provider) {
@@ -115,8 +110,8 @@
static SelectorProvider loadProviderByJar() {
Enumeration<URL> enumeration = null;
- ClassLoader classLoader = AccessController.doPrivileged(
- new PrivilegedAction<ClassLoader>() {
+ ClassLoader classLoader = AccessController
+ .doPrivileged(new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return ClassLoader.getSystemClassLoader();
}
@@ -153,40 +148,37 @@
.substring(0, siteComment);
if (0 < className.length()) {
return (SelectorProvider) classLoader.loadClass(
- className).newInstance();
+ className).newInstance();
}
}
} catch (Exception e) {
throw new Error(e);
- // BEGIN android-added
- // copied from a newer version of harmony
} finally {
try {
br.close();
} catch (IOException ioe) {
// Ignore
}
- // END android-added
}
}
return null;
}
/*
- * load by system property.
+ * Load by system property.
*/
static SelectorProvider loadProviderByProperty() {
- return AccessController.doPrivileged(
- new PrivilegedAction<SelectorProvider>() {
+ return AccessController
+ .doPrivileged(new PrivilegedAction<SelectorProvider>() {
public SelectorProvider run() {
try {
- final String className =
- System.getProperty(PROVIDER_IN_SYSTEM_PROPERTY);
+ final String className = System
+ .getProperty(PROVIDER_IN_SYSTEM_PROPERTY);
if (null != className) {
Class<?> spClass = ClassLoader
.getSystemClassLoader().loadClass(
className);
- return (SelectorProvider)spClass.newInstance();
+ return (SelectorProvider) spClass.newInstance();
}
return null;
} catch (Exception e) {
@@ -202,7 +194,6 @@
* @return the new channel.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract DatagramChannel openDatagramChannel() throws IOException;
@@ -212,7 +203,6 @@
* @return the new pipe.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract Pipe openPipe() throws IOException;
@@ -222,7 +212,6 @@
* @return the new selector.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract AbstractSelector openSelector() throws IOException;
@@ -232,7 +221,6 @@
* @return the new channel.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract ServerSocketChannel openServerSocketChannel()
throws IOException;
@@ -243,7 +231,6 @@
* @return the new channel.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public abstract SocketChannel openSocketChannel() throws IOException;
@@ -257,7 +244,6 @@
* @throws SecurityException
* if there is a security manager installed that does not permit
* the runtime permission labeled "selectorProvider".
- * @since Android 1.0
*/
public Channel inheritedChannel() throws IOException {
// BEGIN android-added
diff --git a/nio/src/main/java/org/apache/harmony/nio/AddressUtil.java b/nio/src/main/java/org/apache/harmony/nio/AddressUtil.java
index 7c094e7..d39b1ea 100644
--- a/nio/src/main/java/org/apache/harmony/nio/AddressUtil.java
+++ b/nio/src/main/java/org/apache/harmony/nio/AddressUtil.java
@@ -1,5 +1,4 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
+/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
@@ -16,7 +15,7 @@
*/
/*
- * Android Notice
+ * Android Notice
* In this class the address length was changed from long to int.
* This is due to performance optimizations for the device.
*/
@@ -26,6 +25,10 @@
import java.io.FileDescriptor;
import java.nio.Buffer;
import java.nio.channels.Channel;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
import org.apache.harmony.luni.platform.FileDescriptorHandler;
import org.apache.harmony.nio.internal.DirectBuffer;
@@ -54,33 +57,9 @@
}
return ((DirectBuffer) buf).getEffectiveAddress().toInt();
}
-
- /**
- * Gets the address of native resource held by the given channel, if has
- * any.
- *
- * For network related channel, including SocketChannel, ServerSocketChannel
- * and DatagramChannel, this method returns a int of Socket handler in Linux
- * while returns a SOCKET (UINT_PTR) in windows.
- *
- * For FileChannel, this method returns the native file descriptor.
- *
- * For other channels, this method return 0, which means unsupported
- * operation.
- *
- * @param channel
- * the given channel which may holds a native resource address
- * @return the address of native resource held by the given channel, if any,
- * otherwise return 0
- */
- public static int getChannelAddress(Channel channel){
- if(channel instanceof FileDescriptorHandler){
- return getFDAddress(((FileDescriptorHandler) channel).getFD());
- }else if(channel instanceof FileChannelImpl){
- return ((FileChannelImpl) channel).getHandle();
- }
- return 0;
- }
- private static native int getFDAddress(FileDescriptor fd);
-}
\ No newline at end of file
+ // BEGIN android-removed: dead code (the native side of which was scary!)
+ //public static int getChannelAddress(Channel channel);
+ //private static native int getFDAddress(FileDescriptor fd);
+ // END android-removed
+}
diff --git a/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java b/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java
index 5abe24a..e44422d 100644
--- a/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java
+++ b/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java
@@ -15,14 +15,13 @@
*/
/*
- * Android Notice
+ * Android Notice
* In this class the address length was changed from long to int.
* This is due to performance optimizations for the device.
*/
package org.apache.harmony.nio;
-
import java.nio.channels.FileChannel;
import org.apache.harmony.nio.internal.ReadOnlyFileChannel;
@@ -37,20 +36,20 @@
*/
public class FileChannelFactory {
public static FileChannel getFileChannel(Object stream, int fd, int mode) {
- switch(mode){
- case IFileSystem.O_RDONLY:
- return new ReadOnlyFileChannel(stream, fd);
- case IFileSystem.O_WRONLY:
- return new WriteOnlyFileChannel(stream, fd);
- case IFileSystem.O_RDWR:
- return new ReadWriteFileChannel(stream, fd);
- case IFileSystem.O_RDWRSYNC:
- return new ReadWriteFileChannel(stream, fd);
- case IFileSystem.O_APPEND:
- return new WriteOnlyFileChannel(stream, fd, true);
- default:
- // nio.09=Unknown file channel type: {0}
- throw new RuntimeException(Messages.getString("nio.09", mode)); //$NON-NLS-1$
+ switch (mode) {
+ case IFileSystem.O_RDONLY:
+ return new ReadOnlyFileChannel(stream, fd);
+ case IFileSystem.O_WRONLY:
+ return new WriteOnlyFileChannel(stream, fd);
+ case IFileSystem.O_RDWR:
+ return new ReadWriteFileChannel(stream, fd);
+ case IFileSystem.O_RDWRSYNC:
+ return new ReadWriteFileChannel(stream, fd);
+ case IFileSystem.O_APPEND:
+ return new WriteOnlyFileChannel(stream, fd, true);
+ default:
+ // nio.09=Unknown file channel type: {0}
+ throw new RuntimeException(Messages.getString("nio.09", mode)); //$NON-NLS-1$
}
}
}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
index ac8f77b..109a819 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
@@ -18,7 +18,6 @@
package org.apache.harmony.nio.internal;
// BEGIN android-note
-// Copied from a newer version of Harmony.
// In this class the address length was changed from long to int.
// END android-note
@@ -46,7 +45,7 @@
import org.apache.harmony.luni.platform.FileDescriptorHandler;
import org.apache.harmony.luni.platform.INetworkSystem;
import org.apache.harmony.luni.platform.Platform;
-import org.apache.harmony.luni.util.ErrorCodeException;
+//import org.apache.harmony.luni.util.ErrorCodeException; android-removed
import org.apache.harmony.nio.AddressUtil;
/*
@@ -62,8 +61,8 @@
// default timeout used to nonblocking mode.
private static final int DEFAULT_TIMEOUT = 1;
- private static final int ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK = -211;
-
+ // android-removed: private static final int ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK = -211;
+
private static final byte[] stubArray = new byte[0];
// The fd to interact with native code
@@ -245,7 +244,7 @@
}
return retAddr;
}
-
+
private SocketAddress receiveImpl(ByteBuffer target, boolean loop)
throws IOException {
SocketAddress retAddr = null;
@@ -256,7 +255,7 @@
receivePacket = new DatagramPacket(target.array(), target
.position()
+ target.arrayOffset(), target.remaining());
- } else {
+ } else {
receivePacket = new DatagramPacket(new byte[target.remaining()],
target.remaining());
}
@@ -285,7 +284,7 @@
}
}
if (null != receivePacket && null != receivePacket.getAddress()) {
-
+
if (received > 0) {
if (target.hasArray()) {
target.position(oldposition + received);
@@ -300,7 +299,7 @@
} while (loop);
return retAddr;
}
-
+
private SocketAddress receiveDirectImpl(ByteBuffer target, boolean loop)
throws IOException {
SocketAddress retAddr = null;
@@ -618,7 +617,7 @@
begin();
int length = buf.remaining();
int start = buf.position();
-
+
if (buf.isDirect()) {
int address = AddressUtil.getDirectBufferAddress(buf);
result = networkSystem.sendConnectedDatagramDirect(fd,
@@ -630,14 +629,7 @@
.array(), start, length, isBound);
}
return result;
- } catch (SocketException e) {
- if (e.getCause() instanceof ErrorCodeException) {
- if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
- .getCause()).getErrorCode()) {
- return result;
- }
- }
- throw e;
+ // android-removed: bogus catch (SocketException e) and use of ErrorCodeException.
} finally {
end(result > 0);
}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/DirectBuffer.java b/nio/src/main/java/org/apache/harmony/nio/internal/DirectBuffer.java
index 52a7b65..1af7c54 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/DirectBuffer.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/DirectBuffer.java
@@ -18,8 +18,7 @@
import org.apache.harmony.luni.platform.PlatformAddress;
public interface DirectBuffer {
- // BEGIN android-changed
- // Copied from a newer version of harmony
+
PlatformAddress getEffectiveAddress();
PlatformAddress getBaseAddress();
@@ -31,5 +30,4 @@
void free();
int getByteCapacity();
- // END android-changed
}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java
index 687b438..9e72082 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java
@@ -16,7 +16,7 @@
*/
/*
- * Android Notice
+ * Android Notice
* In this class the address length was changed from long to int.
* This is due to performance optimizations for the device.
*
@@ -49,7 +49,6 @@
* provided by the port layer.
*
* This class is non-API, but implements the API of the FileChannel interface.
- *
*/
public abstract class FileChannelImpl extends FileChannel {
@@ -73,7 +72,7 @@
// The object that will track all outstanding locks on this channel.
private final LockManager lockManager = new LockManager();
- private class RepositioningLock {}
+ private static class RepositioningLock {}
private final Object repositioningLock = new RepositioningLock();
private final Object stream;
@@ -115,8 +114,7 @@
boolean wait) throws IOException {
if ((position < 0) || (size < 0)) {
// nio.0A=Lock position and size must be non-negative.
- throw new IllegalArgumentException(
- Messages.getString("nio.0A")); //$NON-NLS-1$
+ throw new IllegalArgumentException(Messages.getString("nio.0A")); //$NON-NLS-1$
}
int lockType = shared ? IFileSystem.SHARED_LOCK_TYPE
: IFileSystem.EXCLUSIVE_LOCK_TYPE;
@@ -198,8 +196,8 @@
}
long alignment = position - position % ALLOC_GRANULARITY;
int offset = (int) (position - alignment);
- PlatformAddress address = PlatformAddressFactory.allocMap(handle, alignment, size
- + offset, mapMode);
+ PlatformAddress address = PlatformAddressFactory.allocMap(handle,
+ alignment, size + offset, mapMode);
MappedByteBuffer buffer = null;
try {
buffer = MappedByteBufferFactory.getBuffer(address, mapMode, size,
@@ -225,9 +223,8 @@
openCheck();
if (newPosition < 0) {
// nio.0B=New position must be non-negative.
- throw new IllegalArgumentException(
- Messages.getString("nio.0B")); //$NON-NLS-1$
- }
+ throw new IllegalArgumentException(Messages.getString("nio.0B")); //$NON-NLS-1$
+ }
synchronized (repositioningLock) {
fileSystem.seek(handle, newPosition, IFileSystem.SEEK_SET);
@@ -236,14 +233,14 @@
}
public int read(ByteBuffer buffer, long position) throws IOException {
- if (null == buffer){
+ if (null == buffer) {
throw new NullPointerException();
}
- if (position < 0){
+ if (position < 0) {
throw new IllegalArgumentException();
}
openCheck();
- if (!buffer.hasRemaining()){
+ if (!buffer.hasRemaining()) {
return 0;
}
synchronized (repositioningLock) {
@@ -261,7 +258,7 @@
public int read(ByteBuffer buffer) throws IOException {
openCheck();
- if (!buffer.hasRemaining()){
+ if (!buffer.hasRemaining()) {
return 0;
}
boolean completed = false;
@@ -273,7 +270,7 @@
try {
begin();
/*
- * if (bytesRead <= EOF) delt by read completed = false;
+ * if (bytesRead <= EOF) dealt by read completed = false;
*/
bytesRead = (int) fileSystem.readDirect(handle, address,
buffer.position(), buffer.remaining());
@@ -285,7 +282,7 @@
try {
begin();
/*
- * if (bytesRead <= EOF) delt by read completed = false;
+ * if (bytesRead <= EOF) dealt by read completed = false;
*/
bytesRead = (int) fileSystem.read(handle, buffer.array(),
buffer.arrayOffset() + buffer.position(), buffer
@@ -346,7 +343,7 @@
}
completed = true;
/*
- * if (bytesRead < EOF) //delt by readv? completed = false;
+ * if (bytesRead < EOF) //dealt by readv? completed = false;
*/
} finally {
end(completed);
@@ -367,16 +364,16 @@
}
} else {
ByteBuffer buf = directBuffers[i - offset];
- if (bytesRemaining < buf.remaining()){
- // this is the last step.
+ if (bytesRemaining < buf.remaining()) {
+ // this is the last step.
int pos = buf.position();
buffers[i].put(buf);
- buffers[i].position(pos + (int)bytesRemaining);
+ buffers[i].position(pos + (int) bytesRemaining);
bytesRemaining = 0;
} else {
bytesRemaining -= buf.remaining();
buffers[i].put(buf);
- }
+ }
}
}
return bytesRead;
@@ -403,16 +400,15 @@
if (!src.isOpen()) {
throw new ClosedChannelException();
}
- if (position < 0 || count < 0 || position > Integer.MAX_VALUE
- || count > Integer.MAX_VALUE) {
+ if (position < 0 || count < 0 || count > Integer.MAX_VALUE) {
throw new IllegalArgumentException();
}
- if(position > size()) {
+ if (position > size()) {
return 0;
}
-
+
ByteBuffer buffer = null;
- // BEGIN android-changed
+
try {
if (src instanceof FileChannel) {
FileChannel fileSrc = (FileChannel) src;
@@ -432,10 +428,9 @@
if (buffer != null) {
// all children of FileChannelImpl currently returns
// an instance of DirectBuffer from map() method
- ((DirectBuffer) buffer).free();
+ ((DirectBuffer) buffer).free();
}
}
- // END android-changed
}
public long transferTo(long position, long count, WritableByteChannel target)
@@ -447,11 +442,10 @@
if (target instanceof ReadOnlyFileChannel) {
throw new NonWritableChannelException();
}
- if (position < 0 || count < 0 || position > Integer.MAX_VALUE
- || count > Integer.MAX_VALUE) {
+ if (position < 0 || count < 0) {
throw new IllegalArgumentException();
}
-
+
if (count == 0 || position >= size()) {
return 0;
}
@@ -462,7 +456,7 @@
return kernelTransfer(handle, ((SocketChannelImpl) target).getFD(),
position, count);
}
- // BEGIN android-changed
+
try {
buffer = map(MapMode.READ_ONLY, position, count);
return target.write(buffer);
@@ -474,7 +468,6 @@
((DirectBuffer) buffer).free();
}
}
- // END android-changed
}
private long kernelTransfer(int l, FileDescriptor fd, long position,
@@ -518,14 +511,14 @@
*/
public int write(ByteBuffer buffer, long position) throws IOException {
- if (null == buffer){
+ if (null == buffer) {
throw new NullPointerException();
}
- if (position < 0){
+ if (position < 0) {
throw new IllegalArgumentException();
}
openCheck();
- if (!buffer.hasRemaining()){
+ if (!buffer.hasRemaining()) {
return 0;
}
int bytesWritten = 0;
@@ -653,8 +646,8 @@
}
return bytesWritten;
}
-
- public int getHandle(){
+
+ public int getHandle() {
return handle;
}
}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/FileLockImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/FileLockImpl.java
index 4e0ddc9..bfe360b 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/FileLockImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/FileLockImpl.java
@@ -16,50 +16,54 @@
package org.apache.harmony.nio.internal;
-
import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
-/*
+/**
* The concrete implementation of an NIO file lock object.
- *
*/
final class FileLockImpl extends FileLock {
// Remembers if this lock has been released via the API.
private boolean isReleased = false;
- /*
- * Returns a new file lock object with the given parameters.
+ /**
+ * Answers a new file lock object with the given parameters.
*
- * @param channel the file channel hosting the lock. @param position the
- * start position of the lock, in bytes @param size the length of the lock,
- * in bytes @param shared whether this lock is shared (true) or exclusive
- * (false)
+ * @param channel
+ * the file channel hosting the lock.
+ * @param position
+ * the start position of the lock, in bytes
+ * @param size
+ * the length of the lock, in bytes
+ * @param shared
+ * whether this lock is shared (true) or exclusive (false)
*/
public FileLockImpl(FileChannel channel, long position, long size,
boolean shared) {
super(channel, position, size, shared);
}
- /*
+ /**
* Tests to see if the lock is valid. A lock can be invalidated if the
* channel it is acquired on is closed or if it is released. (non-Javadoc)
*
* @see java.nio.channels.FileLock#isValid()
*/
+ @Override
public boolean isValid() {
return !isReleased && channel().isOpen();
}
- /*
+ /**
* Releases the file lock on the channel that acquired it. Releasing an
* invalid lock has no effect.
*
* @see java.nio.channels.FileLock#release()
*/
+ @Override
public void release() throws IOException {
if (!channel().isOpen()) {
throw new ClosedChannelException();
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java b/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java
index 6752732..816afcf 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java
@@ -29,34 +29,20 @@
import org.apache.harmony.nio.Util;
import org.apache.harmony.nio.internal.nls.Messages;
-
-/*
+/**
* Static methods for I/O util. Used by io package and nio package.
- *
*/
public final class IOUtil {
- // -------------------------------------------------------------------
- // Class variables
- // -------------------------------------------------------------------
-
private static final int DEFAULT_BUFFER_SIZE = 8192;
- // -------------------------------------------------------------------
- // Constructor
- // -------------------------------------------------------------------
-
/*
- * No instance.
+ * Not designed to be instantiated.
*/
private IOUtil() {
super();
}
- // -------------------------------------------------------------------
- // Routine methods.
- // -------------------------------------------------------------------
-
/*
* Read method for InputStreamReader and Channels.
*/
@@ -125,7 +111,7 @@
}
/*
- * refill the buffer from wrapped InputStream
+ * Refill the buffer from wrapped InputStream.
*/
private static void fillBuf(InputStream in, ByteBuffer bytes,
CharBuffer chars, CharsetDecoder decoder) throws IOException {
@@ -211,7 +197,7 @@
}
/*
- * convert function used in write.
+ * Convert function used in write.
*/
private static void convert(Object lock, CharsetEncoder encoder,
ByteBuffer bytes, CharBuffer chars, OutputStream out)
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java b/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java
index f3f5a35..b598c15 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java
@@ -26,17 +26,17 @@
class MappedByteBufferFactory {
- static final Constructor constructor;
+ static final Constructor<?> constructor;
static {
constructor = AccessController
- .doPrivileged(new PrivilegedAction<Constructor>() {
- public Constructor run() {
+ .doPrivileged(new PrivilegedAction<Constructor<?>>() {
+ public Constructor<?> run() {
try {
- Class wrapperClazz = ClassLoader
+ Class<?> wrapperClazz = ClassLoader
.getSystemClassLoader().loadClass(
"java.nio.MappedByteBufferAdapter"); //$NON-NLS-1$
- Constructor result = wrapperClazz
+ Constructor<?> result = wrapperClazz
.getConstructor(new Class[] {
PlatformAddress.class, int.class,
int.class, int.class });
@@ -51,8 +51,10 @@
static MappedByteBuffer getBuffer(PlatformAddress addr, int mapmode,
long size, int offset) throws Exception {
- // Spec points out explicitly that the size of map should be no greater than
- // Integer.MAX_VALUE, so long to int cast is safe here.
+ /*
+ * Spec points out explicitly that the size of map should be no greater
+ * than Integer.MAX_VALUE, so long to int cast is safe here.
+ */
return (MappedByteBuffer) constructor.newInstance(new Object[] { addr,
new Integer((int) size), new Integer(offset),
new Integer(mapmode) });
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/PipeImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/PipeImpl.java
index beceac4..53e9ce6 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/PipeImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/PipeImpl.java
@@ -108,7 +108,7 @@
super(provider);
sourceServer = provider.openServerSocketChannel();
sourceServer.socket().bind(
- new InetSocketAddress(InetAddress.getLocalHost(), 0));
+ new InetSocketAddress(InetAddress.getByName(null), 0));
serverPort = sourceServer.socket().getLocalPort();
}
@@ -161,8 +161,8 @@
}
public boolean finishConnect() throws IOException {
- return sinkSocket.connect(new InetSocketAddress(InetAddress
- .getLocalHost(), serverPort));
+ return sinkSocket.connect(
+ new InetSocketAddress(InetAddress.getByName(null), serverPort));
}
protected void implCloseSelectableChannel() throws IOException {
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/ReadOnlyFileChannel.java b/nio/src/main/java/org/apache/harmony/nio/internal/ReadOnlyFileChannel.java
index 559fc89..359d108 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/ReadOnlyFileChannel.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/ReadOnlyFileChannel.java
@@ -16,7 +16,7 @@
*/
/*
- * Android Notice
+ * Android Notice
* In this class the address length was changed from long to int.
* This is due to performance optimizations for the device.
*/
@@ -40,10 +40,10 @@
}
public final int write(ByteBuffer buffer, long position) throws IOException {
- if (null == buffer){
+ if (null == buffer) {
throw new NullPointerException();
}
- if (position < 0){
+ if (position < 0) {
throw new IllegalArgumentException();
}
throw new NonWritableChannelException();
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/SelectionKeyImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/SelectionKeyImpl.java
index f863928..c6e9930 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/SelectionKeyImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/SelectionKeyImpl.java
@@ -4,9 +4,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,37 +20,41 @@
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.AbstractSelectionKey;
-/*
+/**
* Default implementation of SelectionKey
*/
final class SelectionKeyImpl extends AbstractSelectionKey {
private AbstractSelectableChannel channel;
- int oldInterestOps;
-
private int interestOps;
private int readyOps;
private SelectorImpl selector;
+ // BEGIN android-removed
+ // private int index;
+ // END android-removed
+
public SelectionKeyImpl(AbstractSelectableChannel channel, int operations,
Object attachment, SelectorImpl selector) {
- super();
this.channel = channel;
interestOps = operations;
this.selector = selector;
attach(attachment);
}
+ @Override
public SelectableChannel channel() {
return channel;
}
+ @Override
public int interestOps() {
checkValid();
synchronized (selector.keysLock) {
@@ -58,6 +62,13 @@
}
}
+ int interestOpsNoCheck() {
+ synchronized (selector.keysLock) {
+ return interestOps;
+ }
+ }
+
+ @Override
public SelectionKey interestOps(int operations) {
checkValid();
if ((operations & ~(channel().validOps())) != 0) {
@@ -65,15 +76,20 @@
}
synchronized (selector.keysLock) {
interestOps = operations;
+ // BEGIN android-removed
+ // selector.modKey(this);
+ // END android-removed
}
return this;
}
+ @Override
public int readyOps() {
checkValid();
return readyOps;
}
+ @Override
public Selector selector() {
return selector;
}
@@ -85,10 +101,28 @@
this.readyOps = readyOps;
}
+ // BEGIN android-removed
+ // int getIndex() {
+ // return index;
+ // }
+
+ // void setIndex(int index) {
+ // this.index = index;
+ // }
+ // END android-removed
+
private void checkValid() {
if (!isValid()) {
throw new CancelledKeyException();
}
}
-}
\ No newline at end of file
+ /**
+ * Returns true if the channel for this key is connected. If the channel
+ * does not need connecting, this always return true.
+ */
+ boolean isConnected() {
+ return !(channel instanceof SocketChannel)
+ || ((SocketChannel) channel).isConnected();
+ }
+}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java
index f8e7d80..9d96454 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/SelectorImpl.java
@@ -4,9 +4,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,37 +15,51 @@
*/
package org.apache.harmony.nio.internal;
+// BEGIN android-note
+// This class differs significantly from Harmony. They have adopted indices to
+// track selection keys as-they-change; we avoid that cost by tracking keys on
+// calls to select().
+// END android-note
+
+import org.apache.harmony.luni.platform.FileDescriptorHandler;
+import org.apache.harmony.luni.platform.Platform;
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.IllegalSelectorException;
import java.nio.channels.Pipe;
-import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
+import static java.nio.channels.SelectionKey.*;
import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.AbstractSelectionKey;
import java.nio.channels.spi.AbstractSelector;
import java.nio.channels.spi.SelectorProvider;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.List;
import java.util.Set;
-import org.apache.harmony.luni.platform.FileDescriptorHandler;
-import org.apache.harmony.luni.platform.Platform;
-
/*
* Default implementation of java.nio.channels.Selector
- *
*/
final class SelectorImpl extends AbstractSelector {
+ private static final int[] EMPTY_INT_ARRAY = new int[0];
+
+ private static final FileDescriptor[] EMPTY_FILE_DESCRIPTORS_ARRAY
+ = new FileDescriptor[0];
+ private static final SelectionKeyImpl[] EMPTY_SELECTION_KEY_IMPLS_ARRAY
+ = new SelectionKeyImpl[0];
+
+ private static final int CONNECT_OR_WRITE = OP_CONNECT | OP_WRITE;
+
+ private static final int ACCEPT_OR_READ = OP_ACCEPT | OP_READ;
+
private static final int MOCK_WRITEBUF_SIZE = 1;
private static final int MOCK_READBUF_SIZE = 8;
@@ -60,38 +74,66 @@
private static final int SELECT_NOW = 0;
- // keysLock is used to brief synchronization when get selectionKeys snapshot
- // before selection
- final Object keysLock = new Object();
+ /**
+ * Used to synchronize when a key's interest ops change.
+ */
+ private static class KeysLock {}
+ final Object keysLock = new KeysLock();
- private final Set<SelectionKey> keys = new HashSet<SelectionKey>();
+ private final Set<SelectionKeyImpl> mutableKeys = new HashSet<SelectionKeyImpl>();
+ /**
+ * The unmodifiable set of keys as exposed to the user. This object is used
+ * for synchronization.
+ */
private Set<SelectionKey> unmodifiableKeys = Collections
- .unmodifiableSet(keys);
+ .<SelectionKey>unmodifiableSet(mutableKeys);
- private final Set<SelectionKey> selectedKeys = new HashSet<SelectionKey>();
+ private final Set<SelectionKey> mutableSelectedKeys = new HashSet<SelectionKey>();
- private Set<SelectionKey> unaddableSelectedKeys = new UnaddableSet<SelectionKey>(
- selectedKeys);
+ /**
+ * The unmodifiable set of selectable keys as seen by the user. This object
+ * is used for synchronization.
+ */
+ private final Set<SelectionKey> selectedKeys
+ = new UnaddableSet<SelectionKey>(mutableSelectedKeys);
- // sink and source are used by wakeup()
+ /**
+ * File descriptors we're interested in reading from. When actively
+ * selecting, the first element is always the mock channel's file
+ * descriptor, and the other elements are user-specified file descriptors.
+ * Otherwise, all elements are null.
+ */
+ private FileDescriptor[] readableFDs = EMPTY_FILE_DESCRIPTORS_ARRAY;
+
+ /**
+ * File descriptors we're interested in writing from. May be empty. When not
+ * actively selecting, all elements are null.
+ */
+ private FileDescriptor[] writableFDs = EMPTY_FILE_DESCRIPTORS_ARRAY;
+
+ /**
+ * Selection keys that correspond to the concatenation of readableFDs and
+ * writableFDs. This is used to interpret the results returned by select().
+ * When not actively selecting, all elements are null.
+ */
+ private SelectionKeyImpl[] readyKeys = EMPTY_SELECTION_KEY_IMPLS_ARRAY;
+
+ /**
+ * Selection flags that define the ready ops on the ready keys. When not
+ * actively selecting, all elements are 0. Corresponds to the ready keys
+ * set.
+ */
+ private int[] flags = EMPTY_INT_ARRAY;
+
+ /**
+ * A mock channel is used to signal wakeups. Whenever the selector should
+ * stop blocking on a select(), a byte is written to the sink and will be
+ * picked up in source by the selecting thread.
+ */
private Pipe.SinkChannel sink;
-
private Pipe.SourceChannel source;
-
private FileDescriptor sourcefd;
-
- private SelectionKey[] readableChannels;
-
- private SelectionKey[] writableChannels;
-
- private List<FileDescriptor> readableFDs = new ArrayList<FileDescriptor>();
-
- private List<FileDescriptor> writableFDs = new ArrayList<FileDescriptor>();
-
- private FileDescriptor[] readable;
-
- private FileDescriptor[] writable;
public SelectorImpl(SelectorProvider selectorProvider) {
super(selectorProvider);
@@ -99,67 +141,82 @@
Pipe mockSelector = selectorProvider.openPipe();
sink = mockSelector.sink();
source = mockSelector.source();
- sourcefd = ((FileDescriptorHandler)source).getFD();
+ sourcefd = ((FileDescriptorHandler) source).getFD();
source.configureBlocking(false);
} catch (IOException e) {
- // do nothing
+ // TODO: throw assertion error once IPv6+loopback is fixed
+ e.printStackTrace();
}
}
- /*
+ /**
* @see java.nio.channels.spi.AbstractSelector#implCloseSelector()
*/
+ @Override
protected void implCloseSelector() throws IOException {
- doCancel();
- for (SelectionKey sk : keys) {
- deregister((AbstractSelectionKey) sk);
- }
wakeup();
+ synchronized (this) {
+ synchronized (unmodifiableKeys) {
+ synchronized (selectedKeys) {
+ doCancel();
+ for (SelectionKey sk : mutableKeys) {
+ deregister((AbstractSelectionKey) sk);
+ }
+ }
+ }
+ }
}
- /*
+ /**
* @see java.nio.channels.spi.AbstractSelector#register(java.nio.channels.spi.AbstractSelectableChannel,
* int, java.lang.Object)
*/
+ @Override
protected SelectionKey register(AbstractSelectableChannel channel,
int operations, Object attachment) {
if (!provider().equals(channel.provider())) {
throw new IllegalSelectorException();
}
synchronized (this) {
- synchronized (keys) {
- SelectionKey sk = new SelectionKeyImpl(channel, operations,
- attachment, this);
- keys.add(sk);
- return sk;
+ synchronized (unmodifiableKeys) {
+ SelectionKeyImpl selectionKey = new SelectionKeyImpl(
+ channel, operations, attachment, this);
+ mutableKeys.add(selectionKey);
+ return selectionKey;
}
}
}
- /*
+ /**
* @see java.nio.channels.Selector#keys()
*/
+ @Override
public synchronized Set<SelectionKey> keys() {
closeCheck();
return unmodifiableKeys;
}
+ /*
+ * Checks that the receiver is not closed. If it is throws an exception.
+ */
private void closeCheck() {
if (!isOpen()) {
throw new ClosedSelectorException();
}
}
- /*
+ /**
* @see java.nio.channels.Selector#select()
*/
+ @Override
public int select() throws IOException {
return selectInternal(SELECT_BLOCK);
}
- /*
+ /**
* @see java.nio.channels.Selector#select(long)
*/
+ @Override
public int select(long timeout) throws IOException {
if (timeout < 0) {
throw new IllegalArgumentException();
@@ -167,9 +224,10 @@
return selectInternal((0 == timeout) ? SELECT_BLOCK : timeout);
}
- /*
+ /**
* @see java.nio.channels.Selector#selectNow()
*/
+ @Override
public int selectNow() throws IOException {
return selectInternal(SELECT_NOW);
}
@@ -177,156 +235,184 @@
private int selectInternal(long timeout) throws IOException {
closeCheck();
synchronized (this) {
- synchronized (keys) {
+ synchronized (unmodifiableKeys) {
synchronized (selectedKeys) {
doCancel();
- int[] readyChannels = null;
boolean isBlock = (SELECT_NOW != timeout);
- // BEGIN android-removed
- // copied from newer version of harmony
- // if (keys.size() == 0) {
- // return 0;
- // }
- // END android-removed
- prepareChannels();
+ int readableKeysCount = 1; // first is always the mock channel
+ int writableKeysCount = 0;
+ synchronized (keysLock) {
+ for (SelectionKeyImpl key : mutableKeys) {
+ int ops = key.interestOpsNoCheck();
+ if ((ACCEPT_OR_READ & ops) != 0) {
+ readableKeysCount++;
+ }
+ if ((CONNECT_OR_WRITE & ops) != 0) {
+ writableKeysCount++;
+ }
+ }
+ prepareChannels(readableKeysCount, writableKeysCount);
+ }
+ boolean success;
try {
if (isBlock) {
begin();
}
- readyChannels = Platform.getNetworkSystem().select(readable, writable, timeout);
+ success = Platform.getNetworkSystem().select(
+ readableFDs, writableFDs, readableKeysCount, writableKeysCount, timeout, flags);
} finally {
- // clear results for next select
- readableFDs.clear();
- writableFDs.clear();
if (isBlock) {
end();
}
}
- return processSelectResult(readyChannels);
+
+ int selected = success ? processSelectResult() : 0;
+
+ Arrays.fill(readableFDs, null);
+ Arrays.fill(writableFDs, null);
+ Arrays.fill(readyKeys, null);
+ Arrays.fill(flags, 0);
+
+ selected -= doCancel();
+
+ return selected;
}
}
}
}
- private boolean isConnected(SelectionKeyImpl key) {
- SelectableChannel channel = key.channel();
- if (channel instanceof SocketChannel) {
- return ((SocketChannel) channel).isConnected();
+ /**
+ * Prepare the readableFDs, writableFDs, readyKeys and flags arrays in
+ * preparation for a call to {@code INetworkSystem#select()}. After they're
+ * used, the array elements must be cleared.
+ */
+ private void prepareChannels(int numReadable, int numWritable) {
+ // grow each array to sufficient capacity. Always grow to at least 1.5x
+ // to avoid growing too frequently
+ if (readableFDs.length < numReadable) {
+ int newSize = Math.max((int) (readableFDs.length * 1.5f), numReadable);
+ readableFDs = new FileDescriptor[newSize];
}
- return true;
- }
+ if (writableFDs.length < numWritable) {
+ int newSize = Math.max((int) (writableFDs.length * 1.5f), numWritable);
+ writableFDs = new FileDescriptor[newSize];
+ }
+ int total = numReadable + numWritable;
+ if (readyKeys.length < total) {
+ int newSize = Math.max((int) (readyKeys.length * 1.5f), total);
+ readyKeys = new SelectionKeyImpl[newSize];
+ flags = new int[newSize];
+ }
- // Prepares and adds channels to list for selection
- private void prepareChannels() {
- readableFDs.add(sourcefd);
- List<SelectionKey> readChannelList = new ArrayList<SelectionKey>();
- readChannelList.add(source.keyFor(this));
- List<SelectionKey> writeChannelList = new ArrayList<SelectionKey>();
- synchronized (keysLock) {
- for (Iterator<SelectionKey> i = keys.iterator(); i.hasNext();) {
- SelectionKeyImpl key = (SelectionKeyImpl) i.next();
- key.oldInterestOps = key.interestOps();
- boolean isReadableChannel = ((SelectionKey.OP_ACCEPT | SelectionKey.OP_READ) & key.oldInterestOps) != 0;
- boolean isWritableChannel = ((SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE) & key.oldInterestOps) != 0;
- SelectableChannel channel = key.channel();
- if (isReadableChannel) {
- readChannelList.add(channel.keyFor(this));
- readableFDs.add(((FileDescriptorHandler)channel).getFD());
- }
- if (isWritableChannel) {
- writeChannelList.add(channel.keyFor(this));
- writableFDs.add(((FileDescriptorHandler)channel).getFD());
- }
+ // populate the FDs, including the mock channel
+ readableFDs[0] = sourcefd;
+ int r = 1;
+ int w = 0;
+ for (SelectionKeyImpl key : mutableKeys) {
+ int interestOps = key.interestOpsNoCheck();
+ if ((ACCEPT_OR_READ & interestOps) != 0) {
+ readableFDs[r] = ((FileDescriptorHandler) key.channel()).getFD();
+ readyKeys[r] = key;
+ r++;
+ }
+ if ((CONNECT_OR_WRITE & interestOps) != 0) {
+ writableFDs[w] = ((FileDescriptorHandler) key.channel()).getFD();
+ readyKeys[w + numReadable] = key;
+ w++;
}
}
- readableChannels = readChannelList.toArray(new SelectionKey[0]);
- writableChannels = writeChannelList.toArray(new SelectionKey[0]);
- readable = readableFDs.toArray(new FileDescriptor[0]);
- writable = writableFDs.toArray(new FileDescriptor[0]);
}
- // Analyses selected channels and adds keys of ready channels to
- // selectedKeys list
- private int processSelectResult(int[] readyChannels) throws IOException {
- if (0 == readyChannels.length) {
- return 0;
- }
+ /**
+ * Updates the key ready ops and selected key set with data from the flags
+ * array.
+ */
+ private int processSelectResult() throws IOException {
// if the mock channel is selected, read the content.
- if (READABLE == readyChannels[0]) {
+ if (READABLE == flags[0]) {
ByteBuffer readbuf = ByteBuffer.allocate(MOCK_READBUF_SIZE);
while (source.read(readbuf) > 0) {
readbuf.flip();
}
}
int selected = 0;
- for (int i = 1; i < readyChannels.length; i++) {
- SelectionKeyImpl key = (SelectionKeyImpl) (i >= readable.length ? writableChannels[i
- - readable.length]
- : readableChannels[i]);
- if (null == key) {
+
+ for (int i = 1; i < flags.length; i++) {
+ if (flags[i] == NA) {
continue;
}
- boolean isOldSelectedKey = selectedKeys.contains(key);
+
+ SelectionKeyImpl key = readyKeys[i];
+ int ops = key.interestOpsNoCheck();
int selectedOp = 0;
- // set ready ops
- switch (readyChannels[i]) {
- case NA:
- selectedOp = 0;
- break;
- case READABLE:
- selectedOp = (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)
- & key.oldInterestOps;
- break;
- case WRITEABLE:
- if (isConnected(key)) {
- selectedOp = SelectionKey.OP_WRITE & key.oldInterestOps;
- } else {
- selectedOp = SelectionKey.OP_CONNECT & key.oldInterestOps;
- }
- break;
+
+ switch (flags[i]) {
+ case READABLE:
+ selectedOp = ACCEPT_OR_READ & ops;
+ break;
+ case WRITEABLE:
+ if (key.isConnected()) {
+ selectedOp = OP_WRITE & ops;
+ } else {
+ selectedOp = OP_CONNECT & ops;
+ }
+ break;
}
if (0 != selectedOp) {
- if (isOldSelectedKey && key.readyOps() != selectedOp) {
+ boolean wasSelected = mutableSelectedKeys.contains(key);
+ if (wasSelected && key.readyOps() != selectedOp) {
key.setReadyOps(key.readyOps() | selectedOp);
selected++;
- } else if (!isOldSelectedKey) {
+ } else if (!wasSelected) {
key.setReadyOps(selectedOp);
- selectedKeys.add(key);
+ mutableSelectedKeys.add(key);
selected++;
}
}
}
- readableChannels = null;
- writableChannels = null;
+
return selected;
}
- /*
+ /**
* @see java.nio.channels.Selector#selectedKeys()
*/
+ @Override
public synchronized Set<SelectionKey> selectedKeys() {
closeCheck();
- return unaddableSelectedKeys;
+ return selectedKeys;
}
- private void doCancel() {
+ /**
+ * Removes cancelled keys from the key set and selected key set, and
+ * deregisters the corresponding channels. Returns the number of keys
+ * removed from the selected key set.
+ */
+ private int doCancel() {
+ int deselected = 0;
+
Set<SelectionKey> cancelledKeys = cancelledKeys();
synchronized (cancelledKeys) {
if (cancelledKeys.size() > 0) {
for (SelectionKey currentkey : cancelledKeys) {
+ mutableKeys.remove(currentkey);
deregister((AbstractSelectionKey) currentkey);
- keys.remove(currentkey);
- selectedKeys.remove(currentkey);
+ if (mutableSelectedKeys.remove(currentkey)) {
+ deselected++;
+ }
}
+ cancelledKeys.clear();
}
- cancelledKeys.clear();
}
+
+ return deselected;
}
- /*
+ /**
* @see java.nio.channels.Selector#wakeup()
*/
+ @Override
public Selector wakeup() {
try {
sink.write(ByteBuffer.allocate(MOCK_WRITEBUF_SIZE));
@@ -338,16 +424,18 @@
private static class UnaddableSet<E> implements Set<E> {
- private Set<E> set;
+ private final Set<E> set;
UnaddableSet(Set<E> set) {
this.set = set;
}
+ @Override
public boolean equals(Object object) {
return set.equals(object);
}
+ @Override
public int hashCode() {
return set.hashCode();
}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/SelectorProviderImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/SelectorProviderImpl.java
index d774b3a..0c75808 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/SelectorProviderImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/SelectorProviderImpl.java
@@ -25,10 +25,8 @@
import java.nio.channels.spi.AbstractSelector;
import java.nio.channels.spi.SelectorProvider;
-
/*
* Internal implementation of SelectorProvider.
- *
*/
public class SelectorProviderImpl extends SelectorProvider {
@@ -39,44 +37,38 @@
super();
}
- /*
- *
+ /**
* @see java.nio.channels.spi.SelectorProvider#openDatagramChannel()
*/
public DatagramChannel openDatagramChannel() throws IOException {
return new DatagramChannelImpl(this);
}
- /*
- *
+ /**
* @see java.nio.channels.spi.SelectorProvider#openPipe()
*/
public Pipe openPipe() throws IOException {
return new PipeImpl();
}
- /*
- *
+ /**
* @see java.nio.channels.spi.SelectorProvider#openSelector()
*/
public AbstractSelector openSelector() throws IOException {
return new SelectorImpl(this);
}
- /*
- *
+ /**
* @see java.nio.channels.spi.SelectorProvider#openServerSocketChannel()
*/
public ServerSocketChannel openServerSocketChannel() throws IOException {
return new ServerSocketChannelImpl(this);
}
- /*
- *
+ /**
* @see java.nio.channels.spi.SelectorProvider#openSocketChannel()
*/
public SocketChannel openSocketChannel() throws IOException {
return new SocketChannelImpl(this);
}
-
}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
index dbef656..22d1b4a 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
@@ -126,15 +126,17 @@
synchronized (blockingLock()) {
boolean isBlocking = isBlocking();
if (!isBlocking) {
- // for non blocking mode, use select to see whether
- // there are any pending connections.
- int[] tryResult = Platform.getNetworkSystem().select(
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ int[] tryResult = new int[1];
+ boolean success = Platform.getNetworkSystem().select(
new FileDescriptor[] { this.fd },
- new FileDescriptor[0], 0);
- if (0 == tryResult.length || 0 == tryResult[0]) {
+ new FileDescriptor[0], 1, 0, 0, tryResult);
+ if (!success || 0 == tryResult[0]) {
// no pending connections, returns immediately.
return null;
}
+ // END android-changed
}
// do accept.
do {
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
index 1affb21..cf6d839 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
@@ -18,7 +18,6 @@
package org.apache.harmony.nio.internal;
// BEGIN android-note
-// Copied from a newer version of Harmony.
// In this class the address length was changed from long to int.
// END android-note
@@ -51,7 +50,7 @@
import org.apache.harmony.luni.platform.FileDescriptorHandler;
import org.apache.harmony.luni.platform.INetworkSystem;
import org.apache.harmony.luni.platform.Platform;
-import org.apache.harmony.luni.util.ErrorCodeException;
+//import org.apache.harmony.luni.util.ErrorCodeException; android-removed
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.nio.AddressUtil;
import org.apache.harmony.nio.internal.nls.Messages;
@@ -63,7 +62,7 @@
private static final int EOF = -1;
- private static final int ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK = -211;
+ // android-removed: private static final int ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK = -211;
// The singleton to do the native network operation.
static final INetworkSystem networkSystem = Platform.getNetworkSystem();
@@ -270,7 +269,8 @@
try {
if (isBlocking()) {
begin();
- result = networkSystem.connect(fd, trafficClass, normalAddr, port);
+ networkSystem.connect(fd, trafficClass, normalAddr, port);
+ result = CONNECT_SUCCESS; // Or we'd have thrown an exception.
} else {
result = networkSystem.connectWithTimeout(fd, 0, trafficClass,
normalAddr, port, HY_SOCK_STEP_START, connectContext);
@@ -376,7 +376,7 @@
if (!target.hasRemaining()) {
return 0;
}
-
+
int readCount;
if (target.isDirect() || target.hasArray()) {
readCount = readImpl(target);
@@ -454,9 +454,9 @@
int length = target.remaining();
if (target.isDirect()) {
// BEGIN android-changed
- // changed address from long to int; split address and offset paramters
+ // changed address from long to int
int address = AddressUtil.getDirectBufferAddress(target);
- readCount = networkSystem.readDirect(fd, address, offset,
+ readCount = networkSystem.readDirect(fd, address + offset,
length, (isBlocking() ? TIMEOUT_BLOCK
: TIMEOUT_NONBLOCK));
// END android-changed
@@ -569,14 +569,7 @@
writeCount = networkSystem.write(fd, array, 0, length);
}
source.position(pos + writeCount);
- } catch (SocketException e) {
- if (e.getCause() instanceof ErrorCodeException) {
- if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
- .getCause()).getErrorCode()) {
- return writeCount;
- }
- }
- throw e;
+ // android-removed: bogus catch (SocketException e) and use of ErrorCodeException.
} finally {
if (isBlocking()) {
end(writeCount >= 0);
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/WriteOnlyFileChannel.java b/nio/src/main/java/org/apache/harmony/nio/internal/WriteOnlyFileChannel.java
index ffcdd14..eb46043 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/WriteOnlyFileChannel.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/WriteOnlyFileChannel.java
@@ -16,7 +16,7 @@
*/
/*
- * Android Notice
+ * Android Notice
* In this class the address length was changed from long to int.
* This is due to performance optimizations for the device.
*/
@@ -43,9 +43,10 @@
super(stream, handle);
append = isAppend;
}
-
+
/*
* (non-Javadoc)
+ *
* @see org.apache.harmony.nio.internal.FileChannelImpl#position()
*/
public long position() throws IOException {
@@ -62,7 +63,7 @@
}
public long read(ByteBuffer[] buffers, int offset, int length)
- throws IOException {
+ throws IOException {
if (offset < 0 || length < 0 || offset + length > buffers.length) {
throw new IndexOutOfBoundsException();
}
@@ -75,11 +76,11 @@
throw new NonReadableChannelException();
}
- public int read(ByteBuffer buffer, long position) throws IOException {
+ public int read(ByteBuffer buffer, long position) throws IOException {
if (null == buffer) {
throw new NullPointerException();
}
- if (position < 0){
+ if (position < 0) {
throw new IllegalArgumentException();
}
throw new NonReadableChannelException();
@@ -111,5 +112,4 @@
}
return super.basicLock(position, size, shared, wait);
}
-
}
diff --git a/nio/src/main/native/org_apache_harmony_nio_AddressUtil.cpp b/nio/src/main/native/org_apache_harmony_nio_AddressUtil.cpp
deleted file mode 100644
index cb665de..0000000
--- a/nio/src/main/native/org_apache_harmony_nio_AddressUtil.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#define SOCKET_CAST(x) ((struct hysocket_struct*) x)->sock
-
-typedef jint OSSOCKET;
-
-typedef struct hysocket_struct
-{
- OSSOCKET sock;
- unsigned short family;
-} hysocket_struct;
-
-typedef struct hysocket_struct *hysocket_t;
-
-/*
- * Internal helper function.
- *
- * Get the file descriptor.
- */
-static jint getFd(JNIEnv* env, jclass clazz, jobject fd)
-{
- jclass descriptorCLS;
- jfieldID descriptorFID;
- hysocket_t* hysocketP;
-
- descriptorCLS = env->FindClass("java/io/FileDescriptor");
- if (NULL == descriptorCLS){
- return 0;
- }
- descriptorFID = env->GetFieldID(descriptorCLS, "descriptor", "I");
- if (NULL == descriptorFID){
- return 0;
- }
- jint result = env->GetIntField(fd, descriptorFID);
- hysocketP = (hysocket_t*) (result);
- return SOCKET_CAST(hysocketP);
-}
-
-/*
- * JNI registration
- */
-static JNINativeMethod gMethods[] = {
- /* name, signature, funcPtr */
- { "getFDAddress", "(Ljava/io/FileDescriptor;)I", (void*) getFd }
-};
-
-int register_org_apache_harmony_nio_AddressUtil(JNIEnv* env)
-{
- return jniRegisterNativeMethods(env, "org/apache/harmony/nio/AddressUtil",
- gMethods, NELEM(gMethods));
-}
diff --git a/nio/src/main/native/sub.mk b/nio/src/main/native/sub.mk
deleted file mode 100644
index 750d216..0000000
--- a/nio/src/main/native/sub.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# This file is included by the top-level libcore Android.mk.
-# It's not a normal makefile, so we don't include CLEAR_VARS
-# or BUILD_*_LIBRARY.
-
-LOCAL_SRC_FILES := \
- org_apache_harmony_nio_AddressUtil.cpp
-
-LOCAL_C_INCLUDES +=
-
-# Any shared/static libs that are listed here must also
-# be listed in libs/nativehelper/Android.mk.
-# TODO: fix this requirement
-
-LOCAL_SHARED_LIBRARIES +=
-
-LOCAL_STATIC_LIBRARIES +=
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java
index d7dd36e..049c48b 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferOverflowExceptionTest.java
@@ -74,8 +74,6 @@
SerializationTest.verifyGolden(this, new BufferOverflowException());
}
- // BEGIN android-added
- // copied from newer version of harmony
/**
*@tests {@link java.nio.BufferOverflowException#BufferOverflowException()}
*/
@@ -91,5 +89,4 @@
assertNull(exception.getLocalizedMessage());
assertNull(exception.getCause());
}
- // END android-added
}
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java
index 2c8d09e..d584994 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/BufferUnderflowExceptionTest.java
@@ -77,8 +77,6 @@
SerializationTest.verifyGolden(this, new BufferUnderflowException());
}
- // BEGIN android-added
- // copied from newer version of harmony
/**
*@tests {@link java.nio.BufferUnderflowException#BufferUnderflowException()}
*/
@@ -94,5 +92,4 @@
assertNull(exception.getLocalizedMessage());
assertNull(exception.getCause());
}
- // END android-added
}
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
index b232050..576fec5 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
@@ -1342,6 +1342,30 @@
}
}
+ public void testRead_scenario1() throws Exception {
+ char[] charArray = new char[] { 'a', 'b' };
+ CharBuffer charBuffer = CharBuffer.wrap(charArray);
+ try {
+ charBuffer.read(charBuffer);
+ fail("should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ charBuffer.put(charArray);
+ assertEquals(-1, charBuffer.read(charBuffer));
+ }
+
+ public void testRead_scenario2() throws Exception {
+ CharBuffer charBufferA = CharBuffer.allocate(0);
+ CharBuffer allocateBuffer = CharBuffer.allocate(1);
+ CharBuffer charBufferB = CharBuffer.wrap(allocateBuffer);
+ assertEquals(-1, charBufferA.read(charBufferB));
+
+ allocateBuffer.append(allocateBuffer);
+ charBufferB = CharBuffer.wrap(allocateBuffer);
+ assertEquals(-1, charBufferA.read(charBufferB));
+ }
+
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Abstract method.",
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
index 6256c16..cf2eb48 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
@@ -293,6 +293,17 @@
other.limit(5);
assertTrue(buf.compareTo(other) > 0);
assertTrue(other.compareTo(buf) < 0);
+
+ DoubleBuffer dbuffer1 = DoubleBuffer.wrap(new double[] { Double.NaN });
+ DoubleBuffer dbuffer2 = DoubleBuffer.wrap(new double[] { Double.NaN });
+ DoubleBuffer dbuffer3 = DoubleBuffer.wrap(new double[] { 42d });
+
+ assertEquals("Failed equal comparison with NaN entry", 0, dbuffer1
+ .compareTo(dbuffer2));
+ assertEquals("Failed greater than comparison with NaN entry", 1, dbuffer3
+ .compareTo(dbuffer1));
+ assertEquals("Failed greater than comparison with NaN entry", 1, dbuffer1
+ .compareTo(dbuffer3));
}
@TestTargetNew(
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
index 4d5558c..8edd799 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
@@ -290,8 +290,6 @@
assertTrue(buf.compareTo(other) > 0);
assertTrue(other.compareTo(buf) < 0);
- // BEGIN android-added
- // copied from a newer version of Harmony
FloatBuffer fbuffer1 = FloatBuffer.wrap(new float[] { Float.NaN });
FloatBuffer fbuffer2 = FloatBuffer.wrap(new float[] { Float.NaN });
FloatBuffer fbuffer3 = FloatBuffer.wrap(new float[] { 42f });
@@ -302,7 +300,6 @@
.compareTo(fbuffer1));
assertEquals("Failed greater than comparison with NaN entry", 1, fbuffer1
.compareTo(fbuffer3));
- // END android-added
}
@TestTargetNew(
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java
index 3fd32f55..3278e6b 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/InvalidMarkExceptionTest.java
@@ -56,8 +56,6 @@
SerializationTest.verifyGolden(this, new InvalidMarkException());
}
- // BEGIN android-added
- // copied from newer version of harmony
/**
*@tests {@link java.nio.InvalidMarkException#InvalidMarkException()}
*/
@@ -73,5 +71,4 @@
assertNull(exception.getLocalizedMessage());
assertNull(exception.getCause());
}
- // END android-added
}
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java
index 8c97ae0..f01ed75 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyBufferExceptionTest.java
@@ -73,8 +73,6 @@
SerializationTest.verifyGolden(this, new ReadOnlyBufferException());
}
- // BEGIN android-added
- // copied from newer version of harmony
/**
*@tests {@link java.nio.ReadOnlyBufferException#ReadOnlyBufferException()}
*/
@@ -90,5 +88,4 @@
assertNull(exception.getLocalizedMessage());
assertNull(exception.getCause());
}
- // END android-added
}
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java
index 6767713..1f31121 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AlreadyConnectedExceptionTest.java
@@ -31,6 +31,16 @@
* Tests for AlreadyConnectedException
*/
public class AlreadyConnectedExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.AlreadyConnectedException#AlreadyConnectedException()}
+ */
+ public void test_Constructor() {
+ AlreadyConnectedException e = new AlreadyConnectedException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java
index b9f392d..9752ddc 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AsynchronousCloseExceptionTest.java
@@ -33,6 +33,16 @@
public class AsynchronousCloseExceptionTest extends TestCase {
/**
+ * @tests {@link java.nio.channels.AsynchronousCloseException#AsynchronousCloseException()}
+ */
+ public void test_Constructor() {
+ AsynchronousCloseException e = new AsynchronousCloseException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
+
+ /**
* @tests serialization/deserialization compatibility.
*/
@TestTargets({
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java
index a8edce4..91786d4 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/CancelledKeyExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(CancelledKeyException.class)
public class CancelledKeyExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.CancelledKeyException#CancelledKeyException()}
+ */
+ public void test_Constructor() {
+ CancelledKeyException e = new CancelledKeyException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java
index 8b5dcc7..913598e 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedByInterruptExceptionTest.java
@@ -31,7 +31,16 @@
*/
@TestTargetClass(ClosedByInterruptException.class)
public class ClosedByInterruptExceptionTest extends TestCase {
-
+
+ /**
+ * @tests {@link java.nio.channels.ClosedByInterruptException#ClosedByInterruptException()}
+ */
+ public void test_Constructor() {
+ ClosedByInterruptException e = new ClosedByInterruptException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
*/
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java
index 088b7b5..cc302ed 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedChannelExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(ClosedChannelException.class)
public class ClosedChannelExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.ClosedChannelException#ClosedChannelException()}
+ */
+ public void test_Constructor() {
+ ClosedChannelException e = new ClosedChannelException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java
index 145dd22..232340f 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ClosedSelectorExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(ClosedSelectorException.class)
public class ClosedSelectorExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.ClosedSelectorException#ClosedSelectorException()}
+ */
+ public void test_Constructor() {
+ ClosedSelectorException e = new ClosedSelectorException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java
index e0d6489..6726ca0 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ConnectionPendingExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(ConnectionPendingException.class)
public class ConnectionPendingExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.ConnectionPendingException#ConnectionPendingException()}
+ */
+ public void test_Constructor() {
+ ConnectionPendingException e = new ConnectionPendingException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java
index 36e0082..49c5faa 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/DatagramChannelTest.java
@@ -768,7 +768,7 @@
assertFalse(s.getBroadcast());
assertFalse(s.getReuseAddress());
assertNull(s.getInetAddress());
- assertEquals(s.getLocalAddress().getHostAddress(), "0.0.0.0");
+ assertTrue(s.getLocalAddress().isAnyLocalAddress());
assertEquals(s.getLocalPort(), 0);
assertNull(s.getLocalSocketAddress());
assertEquals(s.getPort(), -1);
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
index 91d6d06..2d96289 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
@@ -1155,6 +1155,25 @@
} catch (IllegalArgumentException e) {
// expected
}
+
+ // BEGIN android-added
+ // Android uses 32-bit off_t, so anything larger than a signed 32-bit int won't work...
+ // ...except for the special case of length == Long.MAX_VALUE, which is used to mean "the
+ // whole file". The special case is tested elsewhere.
+ long tooBig = ((long) Integer.MAX_VALUE) + 1;
+ try {
+ readWriteFileChannel.tryLock(tooBig, 1, false);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ try {
+ readWriteFileChannel.tryLock(0, tooBig, false);
+ fail("should throw IOException");
+ } catch (IOException e) {
+ // expected
+ }
+ // END android-added
}
/**
@@ -4562,6 +4581,52 @@
}
}
+ /**
+ * Regression test for Harmony-3324
+ * Make sure we could delete the file after we called transferTo() method.
+ */
+ public void test_transferTo_couldDelete() throws Exception {
+ // init data in files
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ // call transferTo() method
+ readOnlyFileChannel.transferTo(0 , 2, writeOnlyFileChannel);
+
+ // delete both files
+ readOnlyFileChannel.close();
+ writeOnlyFileChannel.close();
+ boolean rDel = fileOfReadOnlyFileChannel.delete();
+ boolean wDel = fileOfWriteOnlyFileChannel.delete();
+
+ // make sure both files were deleted
+ assertTrue("File " + readOnlyFileChannel + " exists", rDel);
+ assertTrue("File " + writeOnlyFileChannel + " exists", wDel);
+ }
+
+ /**
+ * Regression test for Harmony-3324
+ * Make sure we could delete the file after we called transferFrom() method.
+ */
+ public void test_transferFrom_couldDelete() throws Exception {
+ // init data in files
+ writeDataToFile(fileOfReadOnlyFileChannel);
+ writeDataToFile(fileOfWriteOnlyFileChannel);
+
+ // call transferTo() method
+ writeOnlyFileChannel.transferFrom(readOnlyFileChannel, 0 , 2);
+
+ // delete both files
+ readOnlyFileChannel.close();
+ writeOnlyFileChannel.close();
+ boolean rDel = fileOfReadOnlyFileChannel.delete();
+ boolean wDel = fileOfWriteOnlyFileChannel.delete();
+
+ // make sure both files were deleted
+ assertTrue("File " + readOnlyFileChannel + " exists", rDel);
+ assertTrue("File " + writeOnlyFileChannel + " exists", wDel);
+ }
+
private class MockFileChannel extends FileChannel {
private boolean isLockCalled = false;
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java
index f1ccc96..3b30229 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockInterruptionExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(FileLockInterruptionException.class)
public class FileLockInterruptionExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.FileLockInterruptionException#FileLockInterruptionException()}
+ */
+ public void test_Constructor() {
+ FileLockInterruptionException e = new FileLockInterruptionException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
index 6148b6f..13e6b2d 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
@@ -66,6 +66,12 @@
mockLock = new MockFileLock(readWriteChannel, 10, 100, false);
}
+ protected void tearDown() throws IOException {
+ if (readWriteChannel != null) {
+ readWriteChannel.close();
+ }
+ }
+
/**
* @tests java.nio.channels.FileLock#FileLock(FileChannel, long, long,
* boolean)
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java
index 4b1a840..85e995f 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalBlockingModeExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(IllegalBlockingModeException.class)
public class IllegalBlockingModeExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.IllegalBlockingModeException#IllegalBlockingModeException()}
+ */
+ public void test_Constructor() {
+ IllegalBlockingModeException e = new IllegalBlockingModeException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java
index e8efc31..69066b8 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/IllegalSelectorExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(IllegalSelectorException.class)
public class IllegalSelectorExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.IllegalSelectorException#IllegalSelectorException()}
+ */
+ public void test_Constructor() {
+ IllegalSelectorException e = new IllegalSelectorException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java
index 8efe2ae..e2deb04 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NoConnectionPendingExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(NoConnectionPendingException.class)
public class NoConnectionPendingExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NoConnectionPendingException#NoConnectionPendingException()}
+ */
+ public void test_Constructor() {
+ NoConnectionPendingException e = new NoConnectionPendingException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java
index d255e4b..76002ea 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonReadableChannelExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(NonReadableChannelException.class)
public class NonReadableChannelExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NonReadableChannelException#NonReadableChannelException()}
+ */
+ public void test_Constructor() {
+ NonReadableChannelException e = new NonReadableChannelException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java
index fc23223..60e0cd5 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NonWritableChannelExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(NonWritableChannelException.class)
public class NonWritableChannelExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NonWritableChannelException#NonWritableChannelException()}
+ */
+ public void test_Constructor() {
+ NonWritableChannelException e = new NonWritableChannelException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java
index d76d84a..d0d8df7 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetBoundExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(NotYetBoundException.class)
public class NotYetBoundExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NotYetBoundException#NotYetBoundException()}
+ */
+ public void test_Constructor() {
+ NotYetBoundException e = new NotYetBoundException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java
index e1a8945..4d81c62e 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/NotYetConnectedExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(NotYetConnectedException.class)
public class NotYetConnectedExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.NotYetConnectedException#NotYetConnectedException()}
+ */
+ public void test_Constructor() {
+ NotYetConnectedException e = new NotYetConnectedException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java
index 0c1cc8b..7907369 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/OverlappingFileLockExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(OverlappingFileLockException.class)
public class OverlappingFileLockExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.OverlappingFileLockException#OverlappingFileLockException()}
+ */
+ public void test_Constructor() {
+ OverlappingFileLockException e = new OverlappingFileLockException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
index de69f9f..ee4b02b 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
@@ -23,6 +23,8 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ClosedSelectorException;
@@ -30,8 +32,12 @@
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
+import java.nio.channels.Pipe;
import java.nio.channels.spi.SelectorProvider;
import java.util.Set;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicBoolean;
import junit.framework.TestCase;
import tests.support.Support_PortManager;
@@ -331,29 +337,6 @@
}
/**
- * @test java.nio.channels.Selector#select(long)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies select(long) method for empty selection keys.",
- method = "select",
- args = {long.class}
- )
- public void test_selectJ_Empty_Keys() throws IOException {
- // regression test, see HARMONY-3888.
- // make sure select(long) does wait for specified amount of
- // time if keys.size() == 0 (initial state of selector).
-
- final long SELECT_TIMEOUT = 1000;
-
- long time1 = System.currentTimeMillis();
- selector.select(SELECT_TIMEOUT);
- long time2 = System.currentTimeMillis();
- assertEquals("elapsed time", SELECT_TIMEOUT, (time2 - time1),
- SELECT_TIMEOUT * 0.05); // 5% accuracy
- }
-
- /**
* @tests java.nio.channel.Selector#select(long)
*/
@TestTargetNew(
@@ -400,6 +383,29 @@
}
/**
+ * @test java.nio.channels.Selector#select(long)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies select(long) method for empty selection keys.",
+ method = "select",
+ args = {long.class}
+ )
+ public void test_selectJ_Empty_Keys() throws IOException {
+ // regression test, see HARMONY-3888.
+ // make sure select(long) does wait for specified amount of
+ // time if keys.size() == 0 (initial state of selector).
+
+ final long SELECT_TIMEOUT = 2000;
+
+ long time1 = System.currentTimeMillis();
+ selector.select(SELECT_TIMEOUT);
+ long time2 = System.currentTimeMillis();
+ assertEquals("elapsed time", SELECT_TIMEOUT, (time2 - time1),
+ SELECT_TIMEOUT * 0.05); // 5% accuracy
+ }
+
+ /**
* @tests java.nio.channels.Selector#wakeup()
*/
@TestTargetNew(
@@ -448,6 +454,69 @@
selectOnce(SelectType.TIMEOUT, 0);
}
+ public void test_keySetViewsModifications() throws IOException {
+ Set<SelectionKey> keys = selector.keys();
+
+ SelectionKey key1 = ssc.register(selector, SelectionKey.OP_ACCEPT);
+
+ assertTrue(keys.contains(key1));
+
+ SocketChannel sc = SocketChannel.open();
+ sc.configureBlocking(false);
+ SelectionKey key2 = sc.register(selector, SelectionKey.OP_READ);
+
+ assertTrue(keys.contains(key1));
+ assertTrue(keys.contains(key2));
+
+ key1.cancel();
+ assertTrue(keys.contains(key1));
+
+ selector.selectNow();
+ assertFalse(keys.contains(key1));
+ assertTrue(keys.contains(key2));
+ }
+
+ /**
+ * This test cancels a key while selecting to verify that the cancelled
+ * key set is processed both before and after the call to the underlying
+ * operating system.
+ */
+ public void test_cancelledKeys() throws Exception {
+ final AtomicReference<Throwable> failure = new AtomicReference<Throwable>();
+ final AtomicBoolean complete = new AtomicBoolean();
+
+ final Pipe pipe = Pipe.open();
+ pipe.source().configureBlocking(false);
+ final SelectionKey key = pipe.source().register(selector, SelectionKey.OP_READ);
+
+ Thread thread = new Thread() {
+ public void run() {
+ try {
+ // make sure to call key.cancel() while the main thread is selecting
+ Thread.sleep(500);
+ key.cancel();
+ assertFalse(key.isValid());
+ pipe.sink().write(ByteBuffer.allocate(4)); // unblock select()
+ } catch (Throwable e) {
+ failure.set(e);
+ } finally {
+ complete.set(true);
+ }
+ }
+ };
+ assertTrue(key.isValid());
+
+ thread.start();
+ do {
+ assertEquals(0, selector.select(5000)); // blocks
+ assertEquals(0, selector.selectedKeys().size());
+ } while (!complete.get()); // avoid spurious interrupts
+ assertFalse(key.isValid());
+
+ thread.join();
+ assertNull(failure.get());
+ }
+
private void assert_select_SelectorClosed(SelectType type, int timeout)
throws IOException {
// selector is closed
@@ -669,4 +738,4 @@
return ret;
}
-}
\ No newline at end of file
+}
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
old mode 100755
new mode 100644
index ce34dba..54ef9db
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
@@ -2796,6 +2796,42 @@
}
}
+ public void testReadByteBuffer_Direct2() throws IOException {
+ byte[] request = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ ByteBuffer buffer = ByteBuffer.allocateDirect(128);
+
+ ServerSocketChannel server = ServerSocketChannel.open();
+ server.socket().bind(
+ new InetSocketAddress(InetAddress.getLocalHost(), 0), 5);
+ Socket client = new Socket(InetAddress.getLocalHost(), server.socket()
+ .getLocalPort());
+ client.setTcpNoDelay(false);
+ Socket worker = server.socket().accept();
+ SocketChannel workerChannel = worker.getChannel();
+
+ OutputStream out = client.getOutputStream();
+ out.write(request);
+ out.close();
+
+ buffer.limit(5);
+ int bytesRead = workerChannel.read(buffer);
+ assertEquals(5, bytesRead);
+ assertEquals(5, buffer.position());
+
+ buffer.limit(request.length);
+ bytesRead = workerChannel.read(buffer);
+ assertEquals(6, bytesRead);
+
+ buffer.flip();
+ assertEquals(request.length, buffer.limit());
+
+ assertEquals(ByteBuffer.wrap(request), buffer);
+
+ client.close();
+ worker.close();
+ server.close();
+ }
+
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
@@ -3279,6 +3315,20 @@
* ==========================================================================
*/
+
+ /**
+ * @tests java.nio.channels.SocketChannel#read(ByteBuffer[])
+ */
+ public void test_read$LByteBuffer() throws IOException {
+ MockSocketChannel sc = new MockSocketChannel(null);
+ ByteBuffer [] byteBufferArray = { ByteBuffer.allocate(1), ByteBuffer.allocate(1)};
+ // Verify that calling read(ByteBuffer[]) leads to the method
+ // read(ByteBuffer[], int, int) being called with a 0 for the
+ // second parameter and targets.length as the third parameter.
+ sc.read(byteBufferArray);
+ assertTrue(sc.isReadCalled);
+ }
+
/**
* @tests java.nio.channels.SocketChannel#read(ByteBuffer[],int,int)
*/
@@ -3524,6 +3574,19 @@
}
/**
+ * @tests java.nio.channels.SocketChannel#write(ByteBuffer[])
+ */
+ public void test_write$LByteBuffer() throws IOException {
+ MockSocketChannel sc = new MockSocketChannel(null);
+ ByteBuffer [] byteBufferArray = { ByteBuffer.allocate(1), ByteBuffer.allocate(1)};
+ // Verify that calling write(ByteBuffer[]) leads to the method
+ // write(ByteBuffer[], int, int) being called with a 0 for the
+ // second parameter and sources.length as the third parameter.
+ sc.write(byteBufferArray);
+ assertTrue(sc.isWriteCalled);
+ }
+
+ /**
* @tests java.nio.channels.SocketChannel#write(ByteBuffer[],int,int)
*/
@TestTargetNew(
@@ -4116,6 +4179,39 @@
}
}
+ public void testSocket_setOptions() throws IOException {
+ channel1.connect(localAddr1);
+ Socket socket = channel1.socket();
+
+ ByteBuffer buffer = ByteBuffer.wrap(new byte[] {1, 2, 3});
+ socket.setKeepAlive(true);
+ channel1.write(buffer);
+
+ socket.setOOBInline(true);
+ channel1.write(buffer);
+
+ socket.setReceiveBufferSize(100);
+ channel1.write(buffer);
+
+ socket.setReuseAddress(true);
+ channel1.write(buffer);
+
+ socket.setSendBufferSize(100);
+ channel1.write(buffer);
+
+ socket.setSoLinger(true, 100);
+ channel1.write(buffer);
+
+ socket.setSoTimeout(1000);
+ channel1.write(buffer);
+
+ socket.setTcpNoDelay(true);
+ channel1.write(buffer);
+
+ socket.setTrafficClass(10);
+ channel1.write(buffer);
+ }
+
/**
* @throws IOException
* @tests java.nio.channels.SocketChannel#read(ByteBuffer)
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java
index fe3417f..1838902 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnresolvedAddressExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(UnresolvedAddressException.class)
public class UnresolvedAddressExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.UnresolvedAddressException#UnresolvedAddressException()}
+ */
+ public void test_Constructor() {
+ UnresolvedAddressException e = new UnresolvedAddressException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java
index 442fc1e..97e3eda 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/UnsupportedAddressTypeExceptionTest.java
@@ -31,6 +31,16 @@
*/
@TestTargetClass(UnsupportedAddressTypeException.class)
public class UnsupportedAddressTypeExceptionTest extends TestCase {
+
+ /**
+ * @tests {@link java.nio.channels.UnsupportedAddressTypeException#UnsupportedAddressTypeException()}
+ */
+ public void test_Constructor() {
+ UnsupportedAddressTypeException e = new UnsupportedAddressTypeException();
+ assertNull(e.getMessage());
+ assertNull(e.getLocalizedMessage());
+ assertNull(e.getCause());
+ }
/**
* @tests serialization/deserialization compatibility.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java
index c81efa2..4a2fa73 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AbstractSelectableChannelTest.java
@@ -178,8 +178,17 @@
assertSame(sc, acceptKey.channel());
//test that sc.register invokes Selector.register()
- sc.register(acceptSelector2, SelectionKey.OP_READ, null);
+ acceptKey = sc.register(acceptSelector2, SelectionKey.OP_READ, null);
assertTrue(((MockAbstractSelector)acceptSelector2).isRegisterCalled);
+
+ // Regression test to ensure acceptance of a selector with empty
+ // interest set.
+ SocketChannel channel = SocketChannel.open();
+ channel.configureBlocking(false);
+ Selector selector = Selector.open();
+ channel.register(selector, 0);
+ selector.close();
+ channel.close();
}
/**
diff --git a/nio_char/src/main/java/java/nio/charset/CharacterCodingException.java b/nio_char/src/main/java/java/nio/charset/CharacterCodingException.java
index a6c04bc..eee01f7 100644
--- a/nio_char/src/main/java/java/nio/charset/CharacterCodingException.java
+++ b/nio_char/src/main/java/java/nio/charset/CharacterCodingException.java
@@ -22,8 +22,6 @@
/**
* A {@code CharacterCodingException} is thrown when an encoding or decoding
* error occurs.
- *
- * @since Android 1.0
*/
public class CharacterCodingException extends IOException {
@@ -35,8 +33,6 @@
/**
* Constructs a new {@code CharacterCodingException}.
- *
- * @since Android 1.0
*/
public CharacterCodingException() {
super();
diff --git a/nio_char/src/main/java/java/nio/charset/Charset.java b/nio_char/src/main/java/java/nio/charset/Charset.java
index 045f71f..724699f 100644
--- a/nio_char/src/main/java/java/nio/charset/Charset.java
+++ b/nio_char/src/main/java/java/nio/charset/Charset.java
@@ -37,8 +37,11 @@
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
+import java.util.Vector;
+// BEGIN android-changed
import com.ibm.icu4jni.charset.CharsetProviderICU;
+// END android-changed
/**
* A charset defines a mapping between a Unicode character sequence and a byte
@@ -50,11 +53,9 @@
* also has one or more aliases. The name string can only consist of the
* following characters: '0' - '9', 'A' - 'Z', 'a' - 'z', '.', ':'. '-' and '_'.
* The first character of the name must be a digit or a letter.
- * </p>
* <p>
* The following charsets should be supported by any java platform: US-ASCII,
* ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16.
- * </p>
* <p>
* Additional charsets can be made available by configuring one or more charset
* providers through provider configuration files. Such files are always named
@@ -68,96 +69,62 @@
* comments, are both ignored. Duplicates of names already found are also
* ignored. Both the configuration files and the provider classes will be loaded
* using the thread context class loader.
- * </p>
* <p>
* This class is thread-safe.
- * </p>
- *
+ *
* @see java.nio.charset.spi.CharsetProvider
- * @since Android 1.0
*/
public abstract class Charset implements Comparable<Charset> {
/*
- * --------------------------------------------------------------------
- * Constants
- * --------------------------------------------------------------------
- */
-
- /*
- * the name of configuration files where charset provider class names can be
+ * The name of configuration files where charset provider class names can be
* specified.
*/
private static final String PROVIDER_CONFIGURATION_FILE_NAME = "META-INF/services/java.nio.charset.spi.CharsetProvider"; //$NON-NLS-1$
/*
- * the encoding of configuration files
+ * The encoding of configuration files
*/
private static final String PROVIDER_CONFIGURATION_FILE_ENCODING = "UTF-8"; //$NON-NLS-1$
/*
- * the comment string used in configuration files
+ * The comment string used in configuration files
*/
private static final String PROVIDER_CONFIGURATION_FILE_COMMENT = "#"; //$NON-NLS-1$
private static ClassLoader systemClassLoader;
- /*
- * --------------------------------------------------------------------
- * Class variables
- * --------------------------------------------------------------------
- */
-
// built in provider instance, assuming thread-safe
- private static CharsetProviderICU _builtInProvider = null;
+ // BEGIN android-changed
+ private static final CharsetProviderICU _builtInProvider;
+ // END android-changed
// cached built in charsets
private static TreeMap<String, Charset> _builtInCharsets = null;
- /*
- * --------------------------------------------------------------------
- * Instance variables
- * --------------------------------------------------------------------
- */
-
private final String canonicalName;
// the aliases set
private final HashSet<String> aliasesSet;
// cached Charset table
- private static HashMap<String, Charset> cachedCharsetTable = new HashMap<String, Charset>();
+ private final static HashMap<String, Charset> cachedCharsetTable = new HashMap<String, Charset>();
- // cached CharsetDecoder table
- private static HashMap<String, CharsetDecoder> cachedCharsetDecoderTable = new HashMap<String, CharsetDecoder>();
+ private static boolean inForNameInternal = false;
- // cached CharsetEncoder table
- private static HashMap<String, CharsetEncoder> cachedCharsetEncoderTable = new HashMap<String, CharsetEncoder>();
-
- /*
- * -------------------------------------------------------------------
- * Global initialization
- * -------------------------------------------------------------------
- */
static {
/*
- * create built-in charset provider even if no privilege to access
+ * Create built-in charset provider even if no privilege to access
* charset provider.
*/
_builtInProvider = AccessController
.doPrivileged(new PrivilegedAction<CharsetProviderICU>() {
public CharsetProviderICU run() {
- return new CharsetProviderICU();
- }
+ return new CharsetProviderICU();
+ }
});
}
- /*
- * -------------------------------------------------------------------
- * Constructors
- * -------------------------------------------------------------------
- */
-
/**
* Constructs a <code>Charset</code> object. Duplicated aliases are
* ignored.
@@ -170,11 +137,8 @@
* on an illegal value being supplied for either
* <code>canonicalName</code> or for any element of
* <code>aliases</code>.
- * @since Android 1.0
*/
- protected Charset(String canonicalName, String[] aliases)
- throws IllegalCharsetNameException {
- // throw IllegalArgumentException if name is null
+ protected Charset(String canonicalName, String[] aliases) {
if (null == canonicalName) {
throw new NullPointerException();
}
@@ -192,12 +156,6 @@
}
/*
- * -------------------------------------------------------------------
- * Methods
- * -------------------------------------------------------------------
- */
-
- /*
* Checks whether a character is a special character that can be used in
* charset names, other than letters and digits.
*/
@@ -361,16 +319,22 @@
* Gets a map of all available charsets supported by the runtime.
* <p>
* The returned map contains mappings from canonical names to corresponding
- * instances of <code>Charset</code>. The canonical names can be
- * considered as case-insensitive.
- * </p>
- *
+ * instances of <code>Charset</code>. The canonical names can be considered
+ * as case-insensitive.
+ *
* @return an unmodifiable map of all available charsets supported by the
- * runtime.
- * @since Android 1.0
+ * runtime
*/
@SuppressWarnings("unchecked")
public static SortedMap<String, Charset> availableCharsets() {
+ // BEGIN android-removed
+ // // workaround: conflicted Charsets with icu4j 4.0
+ // Charset.forName("TIS-620");
+ // Charset.forName("windows-1258");
+ // Charset.forName("cp856");
+ // Charset.forName("cp922");
+ // END android-removed
+
// Initialize the built-in charsets map cache if necessary
if (null == _builtInCharsets) {
synchronized (Charset.class) {
@@ -480,53 +444,66 @@
}
/*
- * Gets a <code> Charset </code> instance for the specified charset name. If
+ * Gets a <code>Charset</code> instance for the specified charset name. If
* the charset is not supported, returns null instead of throwing an
* exception.
*/
- private static Charset forNameInternal(String charsetName)
+ private synchronized static Charset forNameInternal(String charsetName)
throws IllegalCharsetNameException {
+ Charset cs = cachedCharsetTable.get(charsetName);
+ if (null != cs) {
+ return cs;
+ }
+
if (null == charsetName) {
throw new IllegalArgumentException();
}
checkCharsetName(charsetName);
- synchronized (Charset.class) {
- // Try to get Charset from cachedCharsetTable
- Charset cs = getCachedCharset(charsetName);
- if (null != cs) {
- return cs;
- }
- // Try built-in charsets
- cs = _builtInProvider.charsetForName(charsetName);
- if (null != cs) {
- cacheCharset(cs);
- return cs;
- }
+ // try built-in charsets
+ // BEGIN android-removed
+ // if (_builtInProvider == null) {
+ // _builtInProvider = new CharsetProviderICU();
+ // }
+ // END android-removed
+ cs = _builtInProvider.charsetForName(charsetName);
+ if (null != cs) {
+ cacheCharset(cs);
+ return cs;
+ }
- // Collect all charsets provided by charset providers
- ClassLoader contextClassLoader = getContextClassLoader();
- Enumeration<URL> e = null;
- try {
- if (null != contextClassLoader) {
- e = contextClassLoader
- .getResources(PROVIDER_CONFIGURATION_FILE_NAME);
+ // collect all charsets provided by charset providers
+ ClassLoader contextClassLoader = getContextClassLoader();
+ Enumeration<URL> e = null;
+ try {
+ if (null != contextClassLoader) {
+ e = contextClassLoader
+ .getResources(PROVIDER_CONFIGURATION_FILE_NAME);
+ } else {
+ getSystemClassLoader();
+ if (systemClassLoader == null) {
+ // Non available during class library start-up phase
+ e = new Vector<URL>().elements();
} else {
- getSystemClassLoader();
e = systemClassLoader
.getResources(PROVIDER_CONFIGURATION_FILE_NAME);
}
- // Examine each configuration file
- while (e.hasMoreElements()) {
- cs = searchConfiguredCharsets(charsetName,
- contextClassLoader, e.nextElement());
- if (null != cs) {
- cacheCharset(cs);
- return cs;
- }
- }
- } catch (IOException ex) {
- // Unexpected ClassLoader exception, ignore
}
+
+ // examine each configuration file
+ while (e.hasMoreElements()) {
+ inForNameInternal = true;
+ cs = searchConfiguredCharsets(charsetName, contextClassLoader,
+ e.nextElement());
+ inForNameInternal = false;
+ if (null != cs) {
+ cacheCharset(cs);
+ return cs;
+ }
+ }
+ } catch (IOException ex) {
+ // Unexpected ClassLoader exception, ignore
+ } finally {
+ inForNameInternal = false;
}
return null;
}
@@ -535,24 +512,21 @@
* save charset into cachedCharsetTable
*/
private static void cacheCharset(Charset cs) {
- cachedCharsetTable.put(cs.name(), cs);
+ if (!cachedCharsetTable.containsKey(cs.name())){
+ cachedCharsetTable.put(cs.name(), cs);
+ }
Set<String> aliasesSet = cs.aliases();
if (null != aliasesSet) {
Iterator<String> iter = aliasesSet.iterator();
while (iter.hasNext()) {
String alias = iter.next();
- cachedCharsetTable.put(alias, cs);
+ if (!cachedCharsetTable.containsKey(alias)) {
+ cachedCharsetTable.put(alias, cs);
+ }
}
}
}
- /*
- * get cached charset reference by name
- */
- private static Charset getCachedCharset(String name) {
- return cachedCharsetTable.get(name);
- }
-
/**
* Gets a <code>Charset</code> instance for the specified charset name.
*
@@ -563,10 +537,8 @@
* if the specified charset name is illegal.
* @throws UnsupportedCharsetException
* if the desired charset is not supported by this runtime.
- * @since Android 1.0
*/
- public static Charset forName(String charsetName)
- throws IllegalCharsetNameException, UnsupportedCharsetException {
+ public static Charset forName(String charsetName) {
Charset c = forNameInternal(charsetName);
if (null == c) {
throw new UnsupportedCharsetException(charsetName);
@@ -582,12 +554,36 @@
* @return true if the specified charset is supported, otherwise false.
* @throws IllegalCharsetNameException
* if the specified charset name is illegal.
- * @since Android 1.0
*/
- public static boolean isSupported(String charsetName)
- throws IllegalCharsetNameException {
- Charset cs = forNameInternal(charsetName);
- return (null != cs);
+ public static synchronized boolean isSupported(String charsetName) {
+ if (inForNameInternal) {
+ Charset cs = cachedCharsetTable.get(charsetName);
+ if (null != cs) {
+ return true;
+ }
+
+ if (null == charsetName) {
+ throw new IllegalArgumentException();
+ }
+ checkCharsetName(charsetName);
+
+ // Try built-in charsets
+ // BEGIN android-removed
+ // if (_builtInProvider == null) {
+ // _builtInProvider = new CharsetProviderICU();
+ // }
+ // END android-removed
+ cs = _builtInProvider.charsetForName(charsetName);
+ if (null != cs) {
+ cacheCharset(cs);
+ return true;
+ }
+ return false;
+ } else {
+ Charset cs = forNameInternal(charsetName);
+ return (null != cs);
+ }
+
}
/**
@@ -598,7 +594,6 @@
* @return true if this charset is a super set of the given charset,
* false if it's unknown or this charset is not a superset of
* the given charset.
- * @since Android 1.0
*/
public abstract boolean contains(Charset charset);
@@ -606,7 +601,6 @@
* Gets a new instance of an encoder for this charset.
*
* @return a new instance of an encoder for this charset.
- * @since Android 1.0
*/
public abstract CharsetEncoder newEncoder();
@@ -614,7 +608,6 @@
* Gets a new instance of a decoder for this charset.
*
* @return a new instance of a decoder for this charset.
- * @since Android 1.0
*/
public abstract CharsetDecoder newDecoder();
@@ -622,7 +615,6 @@
* Gets the canonical name of this charset.
*
* @return this charset's name in canonical form.
- * @since Android 1.0
*/
public final String name() {
return this.canonicalName;
@@ -632,7 +624,6 @@
* Gets the set of this charset's aliases.
*
* @return an unmodifiable set of this charset's aliases.
- * @since Android 1.0
*/
public final Set<String> aliases() {
return Collections.unmodifiableSet(this.aliasesSet);
@@ -641,12 +632,10 @@
/**
* Gets the name of this charset for the default locale.
*
- * This is the default implementation of this method which always returns
- * the canonical name of this charset. Subclasses overriding this Method
- * may return a display name that was localized.
- *
+ * <p>The default implementation returns the canonical name of this charset.
+ * Subclasses may return a localized display name.
+ *
* @return the name of this charset for the default locale.
- * @since Android 1.0
*/
public String displayName() {
return this.canonicalName;
@@ -654,15 +643,13 @@
/**
* Gets the name of this charset for the specified locale.
- *
- * This is the default implementation of this method which always returns
- * the canonical name of this charset. Subclasses overriding this Method
- * may return a display name that was localized.
- *
+ *
+ * <p>The default implementation returns the canonical name of this charset.
+ * Subclasses may return a localized display name.
+ *
* @param l
* a certain locale
- * @return the name of this charset for the specified locale.
- * @since Android 1.0
+ * @return the name of this charset for the specified locale
*/
public String displayName(Locale l) {
return this.canonicalName;
@@ -674,7 +661,6 @@
*
* @return true if the charset is known to be registered, otherwise returns
* false.
- * @since Android 1.0
*/
public final boolean isRegistered() {
return !canonicalName.startsWith("x-") //$NON-NLS-1$
@@ -685,7 +671,6 @@
* Returns true if this charset supports encoding, false otherwise.
*
* @return true if this charset supports encoding, false otherwise.
- * @since Android 1.0
*/
public boolean canEncode() {
return true;
@@ -697,52 +682,32 @@
* <p>
* The default action in case of encoding errors is
* <code>CodingErrorAction.REPLACE</code>.
- * </p>
- *
+ *
* @param buffer
* the character buffer containing the content to be encoded.
* @return the result of the encoding.
- * @since Android 1.0
*/
- synchronized public final ByteBuffer encode(CharBuffer buffer) {
- CharsetEncoder e = getCachedCharsetEncoder(canonicalName);
+ public final ByteBuffer encode(CharBuffer buffer) {
try {
- synchronized (e) {
- return e.encode(buffer);
- }
+ return this.newEncoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE).encode(
+ buffer);
+
} catch (CharacterCodingException ex) {
throw new Error(ex.getMessage(), ex);
}
}
- /*
- * get cached CharsetEncoder by canonical name
- */
- private CharsetEncoder getCachedCharsetEncoder(String name) {
- synchronized (cachedCharsetEncoderTable) {
- CharsetEncoder e = cachedCharsetEncoderTable
- .get(name);
- if (null == e) {
- e = this.newEncoder();
- e.onMalformedInput(CodingErrorAction.REPLACE);
- e.onUnmappableCharacter(CodingErrorAction.REPLACE);
- cachedCharsetEncoderTable.put(name, e);
- }
- return e;
- }
- }
-
/**
* Encodes a string and outputs to a byte buffer that is to be returned.
* <p>
* The default action in case of encoding errors is
* <code>CodingErrorAction.REPLACE</code>.
- * </p>
- *
+ *
* @param s
* the string to be encoded.
* @return the result of the encoding.
- * @since Android 1.0
*/
public final ByteBuffer encode(String s) {
return encode(CharBuffer.wrap(s));
@@ -754,42 +719,25 @@
* <p>
* The default action in case of decoding errors is
* <code>CodingErrorAction.REPLACE</code>.
- * </p>
*
* @param buffer
* the byte buffer containing the content to be decoded.
* @return a character buffer containing the output of the decoding.
- * @since Android 1.0
*/
public final CharBuffer decode(ByteBuffer buffer) {
- CharsetDecoder d = getCachedCharsetDecoder(canonicalName);
+
try {
- synchronized (d) {
- return d.decode(buffer);
- }
+ return this.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE).decode(
+ buffer);
+
} catch (CharacterCodingException ex) {
throw new Error(ex.getMessage(), ex);
}
}
/*
- * get cached CharsetDecoder by canonical name
- */
- private CharsetDecoder getCachedCharsetDecoder(String name) {
- synchronized (cachedCharsetDecoderTable) {
- CharsetDecoder d = cachedCharsetDecoderTable
- .get(name);
- if (null == d) {
- d = this.newDecoder();
- d.onMalformedInput(CodingErrorAction.REPLACE);
- d.onUnmappableCharacter(CodingErrorAction.REPLACE);
- cachedCharsetDecoderTable.put(name, d);
- }
- return d;
- }
- }
-
- /*
* -------------------------------------------------------------------
* Methods implementing parent interface Comparable
* -------------------------------------------------------------------
@@ -803,7 +751,6 @@
* the given object to be compared with.
* @return a negative integer if less than the given object, a positive
* integer if larger than it, or 0 if equal to it.
- * @since Android 1.0
*/
public final int compareTo(Charset charset) {
return this.canonicalName.compareToIgnoreCase(charset.canonicalName);
@@ -822,7 +769,6 @@
* @param obj
* the given object to be compared with.
* @return true if they have the same canonical name, otherwise false.
- * @since Android 1.0
*/
@Override
public final boolean equals(Object obj) {
@@ -837,7 +783,6 @@
* Gets the hash code of this charset.
*
* @return the hash code of this charset.
- * @since Android 1.0
*/
@Override
public final int hashCode() {
@@ -849,7 +794,6 @@
* canonical name of the charset.
*
* @return a string representation of this charset.
- * @since Android 1.0
*/
@Override
public final String toString() {
@@ -860,7 +804,6 @@
* Gets the system default charset from the virtual machine.
*
* @return the default charset.
- * @since Android 1.0
*/
public static Charset defaultCharset() {
Charset defaultCharset = null;
diff --git a/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java b/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
index 38fb9b2..dc243cc 100644
--- a/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
+++ b/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
@@ -44,7 +44,6 @@
* <li>invoking the {@link #flush(CharBuffer) flush} method to flush the
* output.</li>
* </ol>
- * </p>
* <p>
* The {@link #decode(ByteBuffer, CharBuffer, boolean) decode} method will
* convert as many bytes as possible, and the process won't stop until the input
@@ -53,14 +52,12 @@
* indicate the stop reason, and the invoker can identify the result and choose
* further action, which includes filling the input buffer, flushing the output
* buffer or recovering from an error and trying again.
- * </p>
* <p>
* There are two common decoding errors. One is named malformed and it is
* returned when the input byte sequence is illegal for the current specific
* charset, the other is named unmappable character and it is returned when a
* problem occurs mapping a legal input byte sequence to its Unicode character
* equivalent.
- * </p>
* <p>
* Both errors can be handled in three ways, the default one is to report the
* error to the invoker by a {@link CoderResult CoderResult} instance, and the
@@ -72,7 +69,6 @@
* {@link #onMalformedInput(CodingErrorAction) onMalformedInput} method and
* {@link #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter}
* method.
- * </p>
* <p>
* This is an abstract class and encapsulates many common operations of the
* decoding process for all charsets. Decoders for a specific charset should
@@ -81,20 +77,14 @@
* decoding. If a subclass maintains an internal state, it should override the
* {@link #implFlush(CharBuffer) implFlush} method and the
* {@link #implReset() implReset} method in addition.
- * </p>
* <p>
* This class is not thread-safe.
- * </p>
- *
+ *
* @see java.nio.charset.Charset
* @see java.nio.charset.CharsetEncoder
- * @since Android 1.0
*/
public abstract class CharsetDecoder {
- /*
- * --------------------------------------- Consts
- * ---------------------------------------
- */
+
/*
* internal status consts
*/
@@ -106,10 +96,6 @@
private static final int FLUSH = 3;
- /*
- * --------------------------------------- Instance variables
- * ---------------------------------------
- */
// average number of chars for one byte
private float averChars;
@@ -131,10 +117,6 @@
// the current status
private int status;
- /*
- * --------------------------------------- Constructor
- * ---------------------------------------
- */
/**
* Constructs a new <code>CharsetDecoder</code> using the given
* <code>Charset</code>, average number and maximum number of characters
@@ -152,7 +134,6 @@
* @throws IllegalArgumentException
* if <code>averageCharsPerByte</code> or
* <code>maxCharsPerByte</code> is negative.
- * @since Android 1.0
*/
protected CharsetDecoder(Charset charset, float averageCharsPerByte,
float maxCharsPerByte) {
@@ -173,17 +154,12 @@
replace = "\ufffd"; //$NON-NLS-1$
}
- /*
- * --------------------------------------- Methods
- * ---------------------------------------
- */
/**
* Gets the average number of characters created by this decoder for a
* single input byte.
*
* @return the average number of characters created by this decoder for a
* single input byte.
- * @since Android 1.0
*/
public final float averageCharsPerByte() {
return averChars;
@@ -193,7 +169,6 @@
* Gets the <code>Charset</code> which this decoder uses.
*
* @return the <code>Charset</code> which this decoder uses.
- * @since Android 1.0
*/
public final Charset charset() {
return cs;
@@ -205,12 +180,10 @@
* This method decodes the remaining byte sequence of the given byte buffer
* into a new character buffer. This method performs a complete decoding
* operation, resets at first, then decodes, and flushes at last.
- * </p>
* <p>
* This method should not be invoked while another {@code decode} operation
* is ongoing.
- * </p>
- *
+ *
* @param in
* the input buffer.
* @return a new <code>CharBuffer</code> containing the the characters
@@ -233,7 +206,6 @@
* sequence.
* @throws CharacterCodingException
* if another exception happened during the decode operation.
- * @since Android 1.0
*/
public final CharBuffer decode(ByteBuffer in)
throws CharacterCodingException {
@@ -303,7 +275,6 @@
* <p>
* The buffers' position will be changed with the reading and writing
* operation, but their limits and marks will be kept intact.
- * </p>
* <p>
* A <code>CoderResult</code> instance will be returned according to
* following rules:
@@ -332,7 +303,6 @@
* only if the unmappable character action is
* {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}. </li>
* </ul>
- * </p>
* <p>
* The <code>endOfInput</code> parameter indicates that the invoker cannot
* provide further input. This parameter is true if and only if the bytes in
@@ -341,13 +311,11 @@
* then can't provide more input, while it may cause an error if the invoker
* always sets true in several consecutive invocations. This would make the
* remaining input to be treated as malformed input.
- * </p>
* <p>
* This method invokes the
* {@link #decodeLoop(ByteBuffer, CharBuffer) decodeLoop} method to
* implement the basic decode logic for a specific charset.
- * </p>
- *
+ *
* @param in
* the input buffer.
* @param out
@@ -363,7 +331,6 @@
* if the {@link #decodeLoop(ByteBuffer, CharBuffer) decodeLoop}
* method threw an <code>BufferUnderflowException</code> or
* <code>BufferOverflowException</code>.
- * @since Android 1.0
*/
public final CoderResult decode(ByteBuffer in, CharBuffer out,
boolean endOfInput) {
@@ -397,7 +364,10 @@
status = endOfInput ? END : ONGOING;
if (endOfInput && remaining > 0) {
result = CoderResult.malformedForLength(remaining);
+ // BEGIN android-added
+ // needed to adjust for the changed call to position() below
in.position(in.position() + result.length());
+ // END android-added
} else {
return result;
}
@@ -420,12 +390,14 @@
if (action != CodingErrorAction.IGNORE)
return result;
}
+ // BEGIN android-changed
+ // the condition is removed in Harmony revision 518047. However,
+ // making the conditional statement unconditional leads to
+ // misbehavior when using REPLACE on malformedInput.
if (!result.isMalformed()) {
- // Note: the following condition is removed in Harmony revision 518047
- // However, making the conditional statement unconditional
- // leads to misbehavior when using REPLACE on malformedInput.
in.position(in.position() + result.length());
}
+ // END android-changed
}
}
@@ -445,25 +417,21 @@
* {@link #decode(ByteBuffer, CharBuffer, boolean) decode} method, and some
* performance optimized implementation may handle the exception and
* implement the error action itself.
- * </p>
* <p>
* The buffers are scanned from their current positions, and their positions
* will be modified accordingly, while their marks and limits will be
* intact. At most {@link ByteBuffer#remaining() in.remaining()} characters
* will be read, and {@link CharBuffer#remaining() out.remaining()} bytes
* will be written.
- * </p>
* <p>
* Note that some implementations may pre-scan the input buffer and return a
* <code>CoderResult.UNDERFLOW</code> until it receives sufficient input.
- * </p>
*
* @param in
* the input buffer.
* @param out
* the output buffer.
* @return a <code>CoderResult</code> instance indicating the result.
- * @since Android 1.0
*/
protected abstract CoderResult decodeLoop(ByteBuffer in, CharBuffer out);
@@ -473,17 +441,14 @@
* If implementing an auto-detecting charset, then this decoder returns the
* detected charset from this method when it is available. The returned
* charset will be the same for the rest of the decode operation.
- * </p>
* <p>
* If insufficient bytes have been read to determine the charset, an
* <code>IllegalStateException</code> will be thrown.
- * </p>
* <p>
* The default implementation always throws
* <code>UnsupportedOperationException</code>, so it should be overridden
* by a subclass if needed.
- * </p>
- *
+ *
* @return the charset detected by this decoder, or null if it is not yet
* determined.
* @throws UnsupportedOperationException
@@ -491,7 +456,6 @@
* @throws IllegalStateException
* if insufficient bytes have been read to determine the
* charset.
- * @since Android 1.0
*/
public Charset detectedCharset() {
throw new UnsupportedOperationException();
@@ -513,11 +477,10 @@
* space. Otherwise this method will return
* <code>CoderResult.UNDERFLOW</code>, which means one decoding process
* has been completed successfully.
- * </p>
* <p>
* During the flush, the output buffer's position will be changed
* accordingly, while its mark and limit will be intact.
- * </p>
+ *
* @param out
* the given output buffer.
* @return <code>CoderResult.UNDERFLOW</code> or
@@ -529,7 +492,6 @@
* calling {@link #decode(ByteBuffer, CharBuffer, boolean)
* decode(ByteBuffer, CharBuffer, boolean)} with true as value
* for the last boolean parameter.
- * @since Android 1.0
*/
public final CoderResult flush(CharBuffer out) {
if (status != END && status != INIT) {
@@ -551,7 +513,6 @@
* the output buffer.
* @return <code>CoderResult.UNDERFLOW</code> or
* <code>CoderResult.OVERFLOW</code>.
- * @since Android 1.0
*/
protected CoderResult implFlush(CharBuffer out) {
return CoderResult.UNDERFLOW;
@@ -564,7 +525,6 @@
*
* @param newAction
* the new action.
- * @since Android 1.0
*/
protected void implOnMalformedInput(CodingErrorAction newAction) {
// default implementation is empty
@@ -577,7 +537,6 @@
*
* @param newAction
* the new action.
- * @since Android 1.0
*/
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
// default implementation is empty
@@ -589,7 +548,6 @@
*
* @param newReplacement
* the new replacement string.
- * @since Android 1.0
*/
protected void implReplaceWith(String newReplacement) {
// default implementation is empty
@@ -598,8 +556,6 @@
/**
* Reset this decoder's charset related state. The default implementation
* does nothing; this method can be overridden if needed.
- *
- * @since Android 1.0
*/
protected void implReset() {
// default implementation is empty
@@ -610,7 +566,6 @@
*
* @return <code>true</code> if this decoder implements an auto-detecting
* charset.
- * @since Android 1.0
*/
public boolean isAutoDetecting() {
return false;
@@ -625,24 +580,20 @@
* charset has been detected in the input bytes and that the charset can be
* retrieved by invoking the {@link #detectedCharset() detectedCharset}
* method.
- * </p>
* <p>
* Note that a decoder that implements an auto-detecting charset may still
* succeed in decoding a portion of the given input even when it is unable
* to detect the charset. For this reason users should be aware that a
* <code>false</code> return value does not indicate that no decoding took
* place.
- * </p>
* <p>
* The default implementation always throws an
* <code>UnsupportedOperationException</code>; it should be overridden by
* a subclass if needed.
- * </p>
*
* @return <code>true</code> if this decoder has detected a charset.
* @throws UnsupportedOperationException
* if this decoder doesn't implement an auto-detecting charset.
- * @since Android 1.0
*/
public boolean isCharsetDetected() {
throw new UnsupportedOperationException();
@@ -654,7 +605,6 @@
*
* @return this decoder's <code>CodingErrorAction</code> when malformed
* input occurred during the decoding process.
- * @since Android 1.0
*/
public CodingErrorAction malformedInputAction() {
return malformAction;
@@ -666,7 +616,6 @@
*
* @return the maximum number of characters which can be created by this
* decoder for one input byte, must be positive.
- * @since Android 1.0
*/
public final float maxCharsPerByte() {
return maxChars;
@@ -684,7 +633,6 @@
* @return this decoder.
* @throws IllegalArgumentException
* if {@code newAction} is {@code null}.
- * @since Android 1.0
*/
public final CharsetDecoder onMalformedInput(CodingErrorAction newAction) {
if (null == newAction) {
@@ -707,7 +655,6 @@
* @return this decoder.
* @throws IllegalArgumentException
* if {@code newAction} is {@code null}.
- * @since Android 1.0
*/
public final CharsetDecoder onUnmappableCharacter(
CodingErrorAction newAction) {
@@ -723,7 +670,6 @@
* Gets the replacement string, which is never null or empty.
*
* @return the replacement string, cannot be null or empty.
- * @since Android 1.0
*/
public final String replacement() {
return replace;
@@ -744,7 +690,6 @@
* @throws IllegalArgumentException
* if the given replacement cannot satisfy the requirement
* mentioned above.
- * @since Android 1.0
*/
public final CharsetDecoder replaceWith(String newReplacement) {
if (null == newReplacement || newReplacement.length() == 0) {
@@ -767,7 +712,6 @@
* specific charset.
*
* @return this decoder.
- * @since Android 1.0
*/
public final CharsetDecoder reset() {
status = INIT;
@@ -781,7 +725,6 @@
*
* @return this decoder's <code>CodingErrorAction</code> when an
* unmappable character error occurred during the decoding process.
- * @since Android 1.0
*/
public CodingErrorAction unmappableCharacterAction() {
return unmapAction;
diff --git a/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java b/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
index 24b8b3f..f24be92 100644
--- a/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
+++ b/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
@@ -44,7 +44,6 @@
* <li>invoking the {@link #flush(ByteBuffer) flush} method to flush the
* output.</li>
* </ol>
- * </p>
* <p>
* The {@link #encode(CharBuffer, ByteBuffer, boolean) encode} method will
* convert as many characters as possible, and the process won't stop until the
@@ -53,13 +52,11 @@
* returned to indicate the stop reason, and the invoker can identify the result
* and choose further action, which includes filling the input buffer, flushing
* the output buffer or recovering from an error and trying again.
- * </p>
* <p>
* There are two common encoding errors. One is named malformed and it is
* returned when the input content is an illegal 16-bit Unicode character
* sequence, the other is named unmappable character and occurs when there is a
* problem mapping the input to a valid byte sequence in the specified charset.
- * </p>
* <p>
* Both errors can be handled in three ways, the default one is to report the
* error to the invoker by a {@link CoderResult CoderResult} instance, and the
@@ -72,7 +69,6 @@
* the {@link #onMalformedInput(CodingErrorAction) onMalformedInput} method and
* the {@link #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter}
* method.
- * </p>
* <p>
* This class is abstract and encapsulates many common operations of the
* encoding process for all charsets. Encoders for a specific charset should
@@ -81,20 +77,14 @@
* encoding. If a subclass maintains an internal state, it should override the
* {@link #implFlush(ByteBuffer) implFlush} method and the
* {@link #implReset() implReset} method in addition.
- * </p>
* <p>
* This class is not thread-safe.
- * </p>
- *
+ *
* @see java.nio.charset.Charset
* @see java.nio.charset.CharsetDecoder
- * @since Android 1.0
*/
public abstract class CharsetEncoder {
- /*
- * --------------------------------------- Consts
- * ---------------------------------------
- */
+
/*
* internal status consts
*/
@@ -106,10 +96,6 @@
private static final int FLUSH = 3;
- /*
- * --------------------------------------- Instance variables
- * ---------------------------------------
- */
// the Charset which creates this encoder
private Charset cs;
@@ -135,11 +121,6 @@
// checking
private CharsetDecoder decoder;
- /*
- * --------------------------------------- Constructors
- * ---------------------------------------
- */
-
/**
* Constructs a new <code>CharsetEncoder</code> using the given
* <code>Charset</code>, average number and maximum number of bytes
@@ -156,7 +137,6 @@
* @throws IllegalArgumentException
* if <code>maxBytesPerChar</code> or
* <code>averageBytesPerChar</code> is negative.
- * @since Android 1.0
*/
protected CharsetEncoder(Charset cs, float averageBytesPerChar,
float maxBytesPerChar) {
@@ -184,7 +164,6 @@
* {@link #isLegalReplacement(byte[]) isLegalReplacement}.
* @throws IllegalArgumentException
* if any parameters are invalid.
- * @since Android 1.0
*/
protected CharsetEncoder(Charset cs, float averageBytesPerChar,
float maxBytesPerChar, byte[] replacement) {
@@ -205,17 +184,12 @@
replaceWith(replacement);
}
- /*
- * --------------------------------------- Methods
- * ---------------------------------------
- */
/**
* Gets the average number of bytes created by this encoder for a single
* input character.
*
* @return the average number of bytes created by this encoder for a single
* input character.
- * @since Android 1.0
*/
public final float averageBytesPerChar() {
return averBytes;
@@ -227,18 +201,15 @@
* Note that this method can change the internal status of this encoder, so
* it should not be called when another encoding process is ongoing,
* otherwise it will throw an <code>IllegalStateException</code>.
- * </p>
* <p>
* This method can be overridden for performance improvement.
- * </p>
- *
+ *
* @param c
* the given encoder.
* @return true if given character can be encoded by this encoder.
* @throws IllegalStateException
* if another encode process is ongoing so that the current
* internal status is neither RESET or FLUSH.
- * @since Android 1.0
*/
public boolean canEncode(char c) {
return implCanEncode(CharBuffer.wrap(new char[] { c }));
@@ -285,7 +256,6 @@
* this encoder.
* @throws IllegalStateException
* if current internal status is neither RESET or FLUSH.
- * @since Android 1.0
*/
public boolean canEncode(CharSequence sequence) {
CharBuffer cb;
@@ -301,7 +271,6 @@
* Gets the <code>Charset</code> which this encoder uses.
*
* @return the <code>Charset</code> which this encoder uses.
- * @since Android 1.0
*/
public final Charset charset() {
return cs;
@@ -313,11 +282,9 @@
* This method encodes the remaining character sequence of the given
* character buffer into a new byte buffer. This method performs a complete
* encoding operation, resets at first, then encodes, and flushes at last.
- * </p>
* <p>
* This method should not be invoked if another encode operation is ongoing.
- * </p>
- *
+ *
* @param in
* the input buffer.
* @return a new <code>ByteBuffer</code> containing the bytes produced by
@@ -339,7 +306,6 @@
* byte sequence.
* @throws CharacterCodingException
* if other exception happened during the encode operation.
- * @since Android 1.0
*/
public final ByteBuffer encode(CharBuffer in)
throws CharacterCodingException {
@@ -352,31 +318,34 @@
CoderResult result = null;
while (true) {
result = encode(in, output, false);
- checkCoderResult(result);
- if (result.isUnderflow()) {
+ if (result==CoderResult.UNDERFLOW) {
break;
- } else if (result.isOverflow()) {
+ } else if (result==CoderResult.OVERFLOW) {
output = allocateMore(output);
+ continue;
}
+ checkCoderResult(result);
}
result = encode(in, output, true);
checkCoderResult(result);
while (true) {
result = flush(output);
- checkCoderResult(result);
- if (result.isOverflow()) {
- output = allocateMore(output);
- } else {
+ if (result==CoderResult.UNDERFLOW) {
+ output.flip();
break;
+ } else if (result==CoderResult.OVERFLOW) {
+ output = allocateMore(output);
+ continue;
}
- }
-
- output.flip();
- if (result.isMalformed()) {
- throw new MalformedInputException(result.length());
- } else if (result.isUnmappable()) {
- throw new UnmappableCharacterException(result.length());
+ checkCoderResult(result);
+ output.flip();
+ if (result.isMalformed()) {
+ throw new MalformedInputException(result.length());
+ } else if (result.isUnmappable()) {
+ throw new UnmappableCharacterException(result.length());
+ }
+ break;
}
status = FLUSH;
return output;
@@ -387,10 +356,9 @@
*/
private void checkCoderResult(CoderResult result)
throws CharacterCodingException {
- if (result.isMalformed() && malformAction == CodingErrorAction.REPORT) {
+ if (malformAction == CodingErrorAction.REPORT && result.isMalformed() ) {
throw new MalformedInputException(result.length());
- } else if (result.isUnmappable()
- && unmapAction == CodingErrorAction.REPORT) {
+ } else if (unmapAction == CodingErrorAction.REPORT && result.isUnmappable()) {
throw new UnmappableCharacterException(result.length());
}
}
@@ -413,7 +381,6 @@
* <p>
* The buffers' position will be changed with the reading and writing
* operation, but their limits and marks will be kept intact.
- * </p>
* <p>
* A <code>CoderResult</code> instance will be returned according to
* following rules:
@@ -440,7 +407,6 @@
* This kind of result can be returned only on
* {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.</li>
* </ul>
- * </p>
* <p>
* The <code>endOfInput</code> parameter indicates if the invoker can
* provider further input. This parameter is true if and only if the
@@ -450,13 +416,11 @@
* error if the invoker always sets true in several consecutive invocations.
* This would make the remaining input to be treated as malformed input.
* input.
- * </p>
* <p>
* This method invokes the
* {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop} method to
* implement the basic encode logic for a specific charset.
- * </p>
- *
+ *
* @param in
* the input buffer.
* @param out
@@ -471,7 +435,6 @@
* If the {@link #encodeLoop(CharBuffer, ByteBuffer) encodeLoop}
* method threw an <code>BufferUnderflowException</code> or
* <code>BufferUnderflowException</code>.
- * @since Android 1.0
*/
public final CoderResult encode(CharBuffer in, ByteBuffer out,
boolean endOfInput) {
@@ -488,16 +451,19 @@
} catch (BufferUnderflowException e) {
throw new CoderMalfunctionError(e);
}
- if (result.isUnderflow()) {
- int remaining = in.remaining();
+ if (result==CoderResult.UNDERFLOW) {
status = endOfInput ? END : ONGOING;
- if (endOfInput && remaining > 0) {
- result = CoderResult.malformedForLength(remaining);
+ if (endOfInput) {
+ int remaining = in.remaining();
+ if (remaining > 0) {
+ result = CoderResult.malformedForLength(remaining);
+ } else {
+ return result;
+ }
} else {
return result;
}
- }
- if (result.isOverflow()) {
+ } else if (result==CoderResult.OVERFLOW) {
status = endOfInput ? END : ONGOING;
return result;
}
@@ -537,13 +503,13 @@
* {@link #encode(CharBuffer, ByteBuffer, boolean) encode} method, and some
* performance optimized implementation may handle the exception and
* implement the error action itself.
- * </p><p>
+ * <p>
* The buffers are scanned from their current positions, and their positions
* will be modified accordingly, while their marks and limits will be
* intact. At most {@link CharBuffer#remaining() in.remaining()} characters
* will be read, and {@link ByteBuffer#remaining() out.remaining()} bytes
* will be written.
- * </p><p>
+ * <p>
* Note that some implementations may pre-scan the input buffer and return
* <code>CoderResult.UNDERFLOW</code> until it receives sufficient input.
* <p>
@@ -552,7 +518,6 @@
* @param out
* the output buffer.
* @return a <code>CoderResult</code> instance indicating the result.
- * @since Android 1.0
*/
protected abstract CoderResult encodeLoop(CharBuffer in, ByteBuffer out);
@@ -563,7 +528,6 @@
* encoders may need to write some bytes to the output buffer when they have
* read all input characters, subclasses can overridden
* {@link #implFlush(ByteBuffer) implFlush} to perform writing action.
- * </p>
* <p>
* The maximum number of written bytes won't larger than
* {@link ByteBuffer#remaining() out.remaining()}. If some encoder wants to
@@ -572,11 +536,9 @@
* must be called again with a byte buffer that has free space. Otherwise
* this method will return <code>CoderResult.UNDERFLOW</code>, which
* means one encoding process has been completed successfully.
- * </p>
* <p>
* During the flush, the output buffer's position will be changed
* accordingly, while its mark and limit will be intact.
- * </p>
*
* @param out
* the given output buffer.
@@ -589,7 +551,6 @@
* calling {@link #encode(CharBuffer, ByteBuffer, boolean)
* encode(CharBuffer, ByteBuffer, boolean)} with {@code true}
* for the last boolean parameter.
- * @since Android 1.0
*/
public final CoderResult flush(ByteBuffer out) {
if (status != END && status != INIT) {
@@ -611,7 +572,6 @@
* the output buffer.
* @return <code>CoderResult.UNDERFLOW</code> or
* <code>CoderResult.OVERFLOW</code>.
- * @since Android 1.0
*/
protected CoderResult implFlush(ByteBuffer out) {
return CoderResult.UNDERFLOW;
@@ -624,7 +584,6 @@
*
* @param newAction
* the new action.
- * @since Android 1.0
*/
protected void implOnMalformedInput(CodingErrorAction newAction) {
// default implementation is empty
@@ -637,7 +596,6 @@
*
* @param newAction
* the new action.
- * @since Android 1.0
*/
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
// default implementation is empty
@@ -649,7 +607,6 @@
*
* @param newReplacement
* the new replacement string.
- * @since Android 1.0
*/
protected void implReplaceWith(byte[] newReplacement) {
// default implementation is empty
@@ -658,8 +615,6 @@
/**
* Resets this encoder's charset related state. The default implementation
* does nothing; this method can be overridden if needed.
- *
- * @since Android 1.0
*/
protected void implReset() {
// default implementation is empty
@@ -678,7 +633,6 @@
* the given byte array to be checked.
* @return true if the the given argument is legal as this encoder's
* replacement byte array.
- * @since Android 1.0
*/
public boolean isLegalReplacement(byte[] repl) {
if (decoder == null) {
@@ -704,7 +658,6 @@
*
* @return this encoder's <code>CodingErrorAction</code> when a malformed
* input error occurred during the encoding process.
- * @since Android 1.0
*/
public CodingErrorAction malformedInputAction() {
return malformAction;
@@ -716,7 +669,6 @@
*
* @return the maximum number of bytes which can be created by this encoder
* for one input character, must be positive.
- * @since Android 1.0
*/
public final float maxBytesPerChar() {
return maxBytes;
@@ -734,7 +686,6 @@
* @return this encoder.
* @throws IllegalArgumentException
* if the given newAction is null.
- * @since Android 1.0
*/
public final CharsetEncoder onMalformedInput(CodingErrorAction newAction) {
if (null == newAction) {
@@ -758,7 +709,6 @@
* @return this encoder.
* @throws IllegalArgumentException
* if the given newAction is null.
- * @since Android 1.0
*/
public final CharsetEncoder onUnmappableCharacter(
CodingErrorAction newAction) {
@@ -775,7 +725,6 @@
* Gets the replacement byte array, which is never null or empty.
*
* @return the replacement byte array, cannot be null or empty.
- * @since Android 1.0
*/
public final byte[] replacement() {
return replace;
@@ -798,7 +747,6 @@
* @throws IllegalArgumentException
* if the given replacement cannot satisfy the requirement
* mentioned above.
- * @since Android 1.0
*/
public final CharsetEncoder replaceWith(byte[] replacement) {
if (null == replacement || 0 == replacement.length
@@ -818,7 +766,6 @@
* specific charset.
*
* @return this encoder.
- * @since Android 1.0
*/
public final CharsetEncoder reset() {
status = INIT;
@@ -832,7 +779,6 @@
*
* @return this encoder's <code>CodingErrorAction</code> when unmappable
* character occurred during encoding process.
- * @since Android 1.0
*/
public CodingErrorAction unmappableCharacterAction() {
return unmapAction;
diff --git a/nio_char/src/main/java/java/nio/charset/CoderMalfunctionError.java b/nio_char/src/main/java/java/nio/charset/CoderMalfunctionError.java
index 2fc2ae8..b7262a1 100644
--- a/nio_char/src/main/java/java/nio/charset/CoderMalfunctionError.java
+++ b/nio_char/src/main/java/java/nio/charset/CoderMalfunctionError.java
@@ -20,8 +20,6 @@
/**
* A {@code CoderMalfunctionError} is thrown when the encoder/decoder is
* malfunctioning.
- *
- * @since Android 1.0
*/
public class CoderMalfunctionError extends Error {
@@ -36,7 +34,6 @@
*
* @param ex
* the original exception thrown by the encoder/decoder.
- * @since Android 1.0
*/
public CoderMalfunctionError(Exception ex) {
super(ex);
diff --git a/nio_char/src/main/java/java/nio/charset/CoderResult.java b/nio_char/src/main/java/java/nio/charset/CoderResult.java
index 9d47c9f..47df0dd 100644
--- a/nio_char/src/main/java/java/nio/charset/CoderResult.java
+++ b/nio_char/src/main/java/java/nio/charset/CoderResult.java
@@ -40,8 +40,6 @@
* result by calling <code>CoderResult.unmappableForLength(int)</code> with
* the input sequence size indicating the identity of the unmappable character.
* </ol>
- *
- * @since Android 1.0
*/
public class CoderResult {
@@ -60,8 +58,6 @@
/**
* Result object indicating that there is insufficient data in the
* encoding/decoding buffer or that additional data is required.
- *
- * @since Android 1.0
*/
public static final CoderResult UNDERFLOW = new CoderResult(TYPE_UNDERFLOW,
0);
@@ -69,8 +65,6 @@
/**
* Result object used to indicate that the output buffer does not have
* enough space available to store the result of the encoding/decoding.
- *
- * @since Android 1.0
*/
public static final CoderResult OVERFLOW = new CoderResult(TYPE_OVERFLOW, 0);
@@ -116,7 +110,6 @@
* error.
* @throws IllegalArgumentException
* if <code>length</code> is non-positive.
- * @since Android 1.0
*/
public static synchronized CoderResult malformedForLength(int length)
throws IllegalArgumentException {
@@ -147,7 +140,6 @@
* character error.
* @throws IllegalArgumentException
* if <code>length</code> is non-positive.
- * @since Android 1.0
*/
public static synchronized CoderResult unmappableForLength(int length)
throws IllegalArgumentException {
@@ -171,7 +163,6 @@
* Returns true if this result is an underflow condition.
*
* @return true if an underflow, otherwise false.
- * @since Android 1.0
*/
public boolean isUnderflow() {
return this.type == TYPE_UNDERFLOW;
@@ -181,9 +172,8 @@
* Returns true if this result represents a malformed-input error or an
* unmappable-character error.
*
- * @return true if this is a malformed-input error or an
+ * @return true if this is a malformed-input error or an
* unmappable-character error, otherwise false.
- * @since Android 1.0
*/
public boolean isError() {
return this.type == TYPE_MALFORMED_INPUT
@@ -194,7 +184,6 @@
* Returns true if this result represents a malformed-input error.
*
* @return true if this is a malformed-input error, otherwise false.
- * @since Android 1.0
*/
public boolean isMalformed() {
return this.type == TYPE_MALFORMED_INPUT;
@@ -204,7 +193,6 @@
* Returns true if this result is an overflow condition.
*
* @return true if this is an overflow, otherwise false.
- * @since Android 1.0
*/
public boolean isOverflow() {
return this.type == TYPE_OVERFLOW;
@@ -214,7 +202,6 @@
* Returns true if this result represents an unmappable-character error.
*
* @return true if this is an unmappable-character error, otherwise false.
- * @since Android 1.0
*/
public boolean isUnmappable() {
return this.type == TYPE_UNMAPPABLE_CHAR;
@@ -227,7 +214,6 @@
* @return the length, as an integer, of this object's erroneous input.
* @throws UnsupportedOperationException
* if this result is an overflow or underflow.
- * @since Android 1.0
*/
public int length() throws UnsupportedOperationException {
if (this.type == TYPE_MALFORMED_INPUT
@@ -253,7 +239,6 @@
* in case this is a malformed-input error.
* @throws CharacterCodingException
* the default exception.
- * @since Android 1.0
*/
public void throwException() throws BufferUnderflowException,
BufferOverflowException, UnmappableCharacterException,
@@ -272,18 +257,12 @@
}
}
- /*
- * -------------------------------------------------------------------
- * Methods overriding parent class Object
- * -------------------------------------------------------------------
- */
-
/**
* Returns a text description of this result.
*
* @return a text description of this result.
- * @since Android 1.0
*/
+ @Override
public String toString() {
String dsc = null;
switch (this.type) {
diff --git a/nio_char/src/main/java/java/nio/charset/CodingErrorAction.java b/nio_char/src/main/java/java/nio/charset/CodingErrorAction.java
index d949c81..030623b 100644
--- a/nio_char/src/main/java/java/nio/charset/CodingErrorAction.java
+++ b/nio_char/src/main/java/java/nio/charset/CodingErrorAction.java
@@ -20,15 +20,11 @@
* Used to indicate what kind of actions to take in case of encoding/decoding
* errors. Currently three actions are defined: {@code IGNORE}, {@code REPLACE}
* and {@code REPORT}.
- *
- * @since Android 1.0
*/
public class CodingErrorAction {
/**
* Denotes the action to ignore any errors.
- *
- * @since Android 1.0
*/
public static final CodingErrorAction IGNORE = new CodingErrorAction(
"IGNORE"); //$NON-NLS-1$
@@ -36,8 +32,6 @@
/**
* Denotes the action to fill in the output with a replacement character
* when malformed input or an unmappable character is encountered.
- *
- * @since Android 1.0
*/
public static final CodingErrorAction REPLACE = new CodingErrorAction(
"REPLACE"); //$NON-NLS-1$
@@ -46,8 +40,6 @@
* Denotes the action to report the encountered error in an appropriate
* manner, for example to throw an exception or return an informative
* result.
- *
- * @since Android 1.0
*/
public static final CodingErrorAction REPORT = new CodingErrorAction(
"REPORT"); //$NON-NLS-1$
@@ -66,8 +58,8 @@
* Returns a text description of this action indication.
*
* @return a text description of this action indication.
- * @since Android 1.0
*/
+ @Override
public String toString() {
return "Action: " + this.action; //$NON-NLS-1$
}
diff --git a/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java b/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java
index 36ff3ad..fad9fa6 100644
--- a/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java
+++ b/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java
@@ -22,8 +22,6 @@
/**
* An {@code IllegalCharsetNameException} is thrown when an illegal charset name
* is encountered.
- *
- * @since Android 1.0
*/
public class IllegalCharsetNameException extends IllegalArgumentException {
@@ -42,7 +40,6 @@
*
* @param charset
* the encountered illegal charset name.
- * @since Android 1.0
*/
public IllegalCharsetNameException(String charset) {
// niochar.0F=The illegal charset name is "{0}".
@@ -54,7 +51,6 @@
* Gets the encountered illegal charset name.
*
* @return the encountered illegal charset name.
- * @since Android 1.0
*/
public String getCharsetName() {
return this.charsetName;
diff --git a/nio_char/src/main/java/java/nio/charset/MalformedInputException.java b/nio_char/src/main/java/java/nio/charset/MalformedInputException.java
index 9fa0aa2..0a93728 100644
--- a/nio_char/src/main/java/java/nio/charset/MalformedInputException.java
+++ b/nio_char/src/main/java/java/nio/charset/MalformedInputException.java
@@ -22,8 +22,6 @@
/**
* A {@code MalformedInputException} is thrown when a malformed input is
* encountered, for example if a byte sequence is illegal for the given charset.
- *
- * @since Android 1.0
*/
public class MalformedInputException extends CharacterCodingException {
@@ -41,7 +39,6 @@
*
* @param length
* the length of the malformed input.
- * @since Android 1.0
*/
public MalformedInputException(int length) {
this.inputLength = length;
@@ -51,7 +48,6 @@
* Gets the length of the malformed input.
*
* @return the length of the malformed input.
- * @since Android 1.0
*/
public int getInputLength() {
return this.inputLength;
@@ -61,8 +57,8 @@
* Gets a message describing this exception.
*
* @return a message describing this exception.
- * @since Android 1.0
*/
+ @Override
public String getMessage() {
// niochar.05=Malformed input length is {0}.
return Messages.getString("niochar.05", this.inputLength); //$NON-NLS-1$
diff --git a/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java b/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java
index 7cc56e2..db23a6f 100644
--- a/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java
+++ b/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java
@@ -22,8 +22,6 @@
/**
* An {@code UnmappableCharacterException} is thrown when an unmappable
* character for the given charset is encountered.
- *
- * @since Android 1.0
*/
public class UnmappableCharacterException extends CharacterCodingException {
@@ -41,7 +39,6 @@
*
* @param length
* the length of the unmappable character.
- * @since Android 1.0
*/
public UnmappableCharacterException(int length) {
this.inputLength = length;
@@ -51,7 +48,6 @@
* Gets the length of the unmappable character.
*
* @return the length of the unmappable character.
- * @since Android 1.0
*/
public int getInputLength() {
return this.inputLength;
@@ -61,8 +57,8 @@
* Gets a message describing this exception.
*
* @return a message describing this exception.
- * @since Android 1.0
*/
+ @Override
public String getMessage() {
// niochar.0A=The unmappable character length is {0}.
return Messages.getString("niochar.0A", this.inputLength); //$NON-NLS-1$
diff --git a/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java b/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java
index 45dbf3d..b5985b4 100644
--- a/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java
+++ b/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java
@@ -22,8 +22,6 @@
/**
* An {@code UnsupportedCharsetException} is thrown when an unsupported charset
* name is encountered.
- *
- * @since Android 1.0
*/
public class UnsupportedCharsetException extends IllegalArgumentException {
@@ -37,11 +35,11 @@
private String charsetName;
/**
- * Constructs a new {@code UnsupportedCharsetException} with the supplied charset name.
+ * Constructs a new {@code UnsupportedCharsetException} with the supplied
+ * charset name.
*
* @param charset
* the encountered unsupported charset name.
- * @since Android 1.0
*/
public UnsupportedCharsetException(String charset) {
// niochar.04=The unsupported charset name is "{0}".
@@ -53,7 +51,6 @@
* Gets the encountered unsupported charset name.
*
* @return the encountered unsupported charset name.
- * @since Android 1.0
*/
public String getCharsetName() {
return this.charsetName;
diff --git a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
index 5908b14..70c6c8f 100644
--- a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
+++ b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
@@ -21,6 +21,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestLevel;
+import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
@@ -32,6 +33,7 @@
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.MalformedInputException;
+import java.util.Arrays;
import junit.framework.TestCase;
@TestTargetClass(CharsetDecoder.class)
@@ -271,4 +273,51 @@
return CoderResult.UNDERFLOW;
}
}
+
+
+ public void testInvalidDecoding() throws IOException {
+
+ byte[][] invalidSequences = new byte[][] {
+ // overlong NULL
+ { (byte) 0xC0, (byte) 0x80 },
+ // overlong ascii 'A'
+ { (byte) 0xC0, (byte) 0xC1 },
+ // overlong "/../"
+ { (byte) 0x2F, (byte) 0xC0, (byte) 0xAE, (byte) 0x2E, (byte) 0x2F },
+ // Invalid encoding 2r11111000 (sequence too long)
+ { (byte) 0xF8 },
+ // Invalid encoding 2r10000000 (sequence too short)
+ { (byte) 0x80 }
+ };
+
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+
+ /*
+ * When bytebuffer has a backing array...
+ */
+ for (byte[] bytes : invalidSequences) {
+ try {
+ decoder.decode(ByteBuffer.wrap(bytes));
+ fail("No exception thrown on " + Arrays.toString(bytes));
+ } catch (MalformedInputException e) {
+ // expected
+ }
+ }
+
+ /*
+ * When bytebuffer has _not_ got a backing array...
+ */
+ for (byte[] bytes : invalidSequences) {
+ try {
+ ByteBuffer bb = ByteBuffer.allocateDirect(8);
+ bb.put(bytes).flip();
+ decoder.decode(bb);
+ fail("No exception thrown on " + Arrays.toString(bytes));
+ } catch (MalformedInputException e) {
+ // expected
+ }
+ }
+ }
+
}
diff --git a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java
index 1f33a05..c3e2256 100644
--- a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java
+++ b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetEncoderTest.java
@@ -21,6 +21,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestLevel;
+import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
@@ -203,4 +204,22 @@
assertEquals(4, out.remaining());
assertTrue(result.isMalformed());
}
+
+ /**
+ * @tests {@link java.nio.charset.Charset#encode(java.nio.CharBuffer)
+ */
+ public void testUtf8Encoding() throws IOException {
+ byte[] orig = new byte[] { (byte) 0xed, (byte) 0xa0,
+ (byte) 0x80 };
+ String s = new String(orig, "UTF-8");
+ assertEquals(1, s.length());
+ assertEquals(55296, s.charAt(0));
+ Charset.forName("UTF-8").encode(CharBuffer.wrap(s));
+// ByteBuffer buf = <result>
+// for (byte o : orig) {
+// byte b = 0;
+// buf.get(b);
+// assertEquals(o, b);
+// }
+ }
}
diff --git a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java
index f8b0b7e..e7c5f5c 100644
--- a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java
+++ b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetTest.java
@@ -16,24 +16,18 @@
package org.apache.harmony.nio_char.tests.java.nio.charset;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import junit.framework.TestCase;
+import tests.util.TestEnvironment;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
import java.nio.charset.IllegalCharsetNameException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
-
-import junit.framework.TestCase;
@TestTargetClass(Charset.class)
public class CharsetTest extends TestCase {
@@ -47,6 +41,8 @@
* JUnit set-up method
*/
public void setUp() {
+ TestEnvironment.reset();
+
// Populate the known charset vars
Set names = Charset.availableCharsets().keySet();
for (Iterator nameItr = names.iterator(); nameItr.hasNext();) {
@@ -181,153 +177,4 @@
Charset cs4 = Charset.forName("US-ASCII");
assertSame(cs3, cs4);
}
-
- /*
- * test cached decoder
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "This test is quite useless for the rest it does, though.",
- method = "Charset",
- args = {java.lang.String.class, java.lang.String[].class}
- )
- public void test_DecodeLjava_nio_ByteBuffer() throws Exception{
- MockCharsetForDecoder cs1 = new MockCharsetForDecoder("CachedCharset",null);
- MockCharsetForDecoder cs2 = new MockCharsetForDecoder("CachedCharset",null);
- ByteBuffer in = ByteBuffer.wrap(new byte[]{0x00});
- cs1.decode(in);
- in.flip();
- cs2.decode(in);
- in.flip();
- }
- /*
- * Mock Charset for cached decoder test
- */
- static class MockCharsetForDecoder extends Charset{
-
- public MockCharsetForDecoder(String canonicalName, String[] aliases){
- super(canonicalName, aliases);
- }
-
- public boolean contains(Charset charset) {
- return false;
- }
-
- public CharsetEncoder newEncoder() {
- return null;
- }
-
- public CharsetDecoder newDecoder() {
- return new MockCachedDecoder(this);
- }
-
-
- }
- /*
- * Mock decoder. Only one caller is permitted.
- */
- static class MockCachedDecoder extends CharsetDecoder {
- static MockCachedDecoder caller = null;
-
- public MockCachedDecoder(Charset cs) {
- super(cs, 1, 10);
- }
-
- /*
- * Only one caller is permitted.
- * If there's another caller, throw RuntimeException.
- */
- protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
- if(null == caller){
- caller = this;
- }else{
- if(caller != this){
- // Another instance
- fail("should use the same instance");
- }
- }
- return CoderResult.UNDERFLOW;
- }
- }
-
- /*
- * test cached encoder
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Functional test.",
- method = "encode",
- args = {java.nio.CharBuffer.class}
- )
- public void test_EncodeLjava_nio_CharBuffer() throws Exception {
- MockCharsetForEncoder cs1 = new MockCharsetForEncoder("CachedCharset", null);
- MockCharsetForEncoder cs2 = new MockCharsetForEncoder("CachedCharset", null);
- CharBuffer in = CharBuffer.wrap("A");
- cs1.encode(in);
- in.flip();
- cs2.encode(in);
- }
-
- /*
- * Mock Charset for cached encoder test
- */
- static class MockCharsetForEncoder extends Charset {
-
- public MockCharsetForEncoder(String canonicalName, String[] aliases) {
- super(canonicalName, aliases);
- }
-
- public boolean contains(Charset charset) {
- return false;
- }
-
- public CharsetDecoder newDecoder() {
- return new MockDecoderForEncoder(this);
- }
-
- public CharsetEncoder newEncoder() {
- return new MockCachedEncoder(this);
- }
- }
-
- /*
- * Mock encoder. Only one caller is permitted.
- */
- static class MockCachedEncoder extends CharsetEncoder {
- static MockCachedEncoder caller = null;
-
- public MockCachedEncoder(Charset cs) {
- super(cs, 1, 10);
- }
-
- /*
- * Only one caller is permitted.
- */
- protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
- if (null == caller) {
- caller = this;
- } else {
- if (caller != this) {
- // Another instance
- fail("should use the same instance");
- }
- }
- return CoderResult.UNDERFLOW;
- }
- }
-
- /*
- * Mock decoder for MockCachedEncoder.
- */
- static class MockDecoderForEncoder extends CharsetDecoder {
- public MockDecoderForEncoder(Charset cs) {
- super(cs, 1, 10);
- }
-
- protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
- in.position(in.limit());
- return CoderResult.UNDERFLOW;
- }
- }
-
}
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java b/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
index 88cbbdb..ff6fe42 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package tests.api.java.nio.charset;
import java.nio.ByteBuffer;
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java
index 927a96f..06d7da2 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetDecoderTest.java
@@ -20,13 +20,18 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.UnsupportedCharsetException;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+
@TestTargetClass(CharsetDecoder.class)
/**
* API unit test for java.nio.charset.CharsetDecoder
@@ -37,14 +42,35 @@
protected static final double AVER_BYTES = 0.5;
-
protected void setUp() throws Exception {
cs = new CharsetEncoderTest.MockCharset("mock", new String[0]);
unibytes = new byte[] { 32, 98, 117, 102, 102, 101, 114 };
+ decoder = cs.newDecoder();
+
+ // for this test's weird superclass, super.setUp() needs to be run last
super.setUp();
}
+ public void testDefaultValues() {
+ assertSame(cs, decoder.charset());
+ try {
+ decoder.detectedCharset();
+ fail("should unsupported");
+ } catch (UnsupportedOperationException e) {
+ }
+ try {
+ assertTrue(decoder.isCharsetDetected());
+ fail("should unsupported");
+ } catch (UnsupportedOperationException e) {
+ }
+ assertFalse(decoder.isAutoDetecting());
+ assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
+ assertSame(CodingErrorAction.REPORT, decoder
+ .unmappableCharacterAction());
+ assertEquals(decoder.replacement(), "\ufffd");
+ }
+
/*
* test constructor
*/
@@ -127,6 +153,615 @@
}
}
+ /*
+ * test onMalformedInput
+ */
+ public void testOnMalformedInput() {
+ assertSame(CodingErrorAction.REPORT, decoder.malformedInputAction());
+ try {
+ decoder.onMalformedInput(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ decoder.onMalformedInput(CodingErrorAction.IGNORE);
+ assertSame(CodingErrorAction.IGNORE, decoder.malformedInputAction());
+ }
+
+ /*
+ * test unmappableCharacter
+ */
+ public void testOnUnmappableCharacter() {
+ assertSame(CodingErrorAction.REPORT, decoder
+ .unmappableCharacterAction());
+ try {
+ decoder.onUnmappableCharacter(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ assertSame(CodingErrorAction.IGNORE, decoder
+ .unmappableCharacterAction());
+ }
+
+ /*
+ * test replaceWith
+ */
+ public void testReplaceWith() {
+ try {
+ decoder.replaceWith(null);
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ decoder.replaceWith("");
+ fail("should throw null pointer exception");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ decoder.replaceWith("testReplaceWith");
+ fail("should throw illegal argument exception");
+ } catch (IllegalArgumentException e) {
+ }
+
+ decoder.replaceWith("a");
+ assertSame("a", decoder.replacement());
+ }
+
+ /*
+ * Class under test for CharBuffer decode(ByteBuffer)
+ */
+ public void testDecodeByteBuffer() throws CharacterCodingException {
+ implTestDecodeByteBuffer();
+ }
+
+ void implTestDecodeByteBuffer() throws CharacterCodingException {
+ // Null pointer
+ try {
+ decoder.decode(null);
+ fail("should throw null pointer exception");
+ } catch (NullPointerException e) {
+ }
+
+ // empty input buffer
+ CharBuffer out = decoder.decode(ByteBuffer.allocate(0));
+ assertCharBufferValue("", out);
+
+ // normal case
+ ByteBuffer in = getByteBuffer();
+ out = decoder.decode(in);
+ assertEquals(0, out.position());
+ assertEquals(getString().length(), out.limit());
+ assertEquals(getString().length(), out.remaining());
+ assertCharBufferValue(getString(), out);
+
+ // normal read only case
+ in = getByteBuffer().asReadOnlyBuffer();
+ out = decoder.decode(in);
+ assertEquals(out.position(), 0);
+ assertEquals(out.limit(), getString().length());
+ assertEquals(out.remaining(), getString().length());
+ assertCharBufferValue(getString(), out);
+ }
+
+ public void testDecodeByteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ CharBuffer out;
+ ByteBuffer in;
+ String replaceStr = decoder.replacement() + getString();
+
+ // MalformedException:
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ in = getMalformedByteBuffer();
+ if (in != null) {
+ try {
+ CharBuffer buffer = decoder.decode(in);
+ assertTrue(buffer.remaining() > 0);
+ fail("should throw MalformedInputException");
+ } catch (MalformedInputException e) {
+ }
+
+ decoder.reset();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.IGNORE);
+ out = decoder.decode(in);
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.REPLACE);
+ out = decoder.decode(in);
+ assertCharBufferValue(replaceStr, out);
+ }
+
+ // Unmapped Exception:
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ in = getUnmappedByteBuffer();
+ if (in != null) {
+ try {
+ decoder.decode(in);
+ fail("should throw UnmappableCharacterException");
+ } catch (UnmappableCharacterException e) {
+ }
+
+ decoder.reset();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ out = decoder.decode(in);
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ out = decoder.decode(in);
+ assertCharBufferValue(replaceStr, out);
+ }
+
+ // RuntimeException
+ try {
+ decoder.decode(getExceptionByteArray());
+ fail("should throw runtime exception");
+ } catch (RuntimeException e) {
+ }
+ }
+
+ /*
+ * Class under test for CoderResult decode(ByteBuffer, CharBuffer, boolean)
+ */
+ public void testDecodeByteBufferCharBuffer() {
+ implTestDecodeByteBufferCharBuffer(getByteBuffer());
+ }
+
+ public void testDecodeByteBufferCharBufferReadOnly() {
+ implTestDecodeByteBufferCharBuffer(getByteBuffer());
+ }
+
+ void implTestDecodeByteBufferCharBuffer(ByteBuffer in) {
+ CharBuffer out = CharBuffer.allocate(100);
+
+ // Null pointer
+ decoder.reset();
+ try {
+ decoder.decode(null, out, true);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ }
+ try {
+ decoder.decode(in, null, true);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ }
+
+ // normal case, one complete operation
+ decoder.reset();
+ in.rewind();
+ out.rewind();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
+ assertEquals(out.limit(), 100);
+ assertEquals(out.position(), getString().length());
+ assertEquals(out.remaining(), 100 - getString().length());
+ assertEquals(out.capacity(), 100);
+ assertCharBufferValue(getString(), out);
+ decoder.flush(out);
+
+ // normal case, one complete operation, but call twice, first time set
+ // endOfInput to false
+ decoder.reset();
+ in.rewind();
+ out.clear();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ assertEquals(out.limit(), 100);
+ assertEquals(out.position(), getString().length());
+ assertEquals(out.remaining(), 100 - getString().length());
+ assertEquals(out.capacity(), 100);
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ in.rewind();
+ out.clear();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ in = getHeadlessByteBuffer();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ in.rewind();
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
+ assertEquals(out.limit(), 100);
+ assertTrue(out.position() > 0);
+ assertEquals(out.remaining(), out.capacity() - out.position());
+ assertEquals(out.capacity(), 100);
+ assertCharBufferValue(getString() + getString() + getString(), out);
+
+ // overflow
+ out = CharBuffer.allocate(4);
+ decoder.reset();
+ in = getByteBuffer();
+ out.rewind();
+ assertSame(CoderResult.OVERFLOW, decoder.decode(in, out, false));
+
+ assertCharBufferValue(getString().substring(0, 4), out);
+ out = CharBuffer.allocate(100);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, false));
+ assertCharBufferValue(getString().substring(4), out);
+ in.rewind();
+ out = CharBuffer.allocate(100);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, true));
+ assertCharBufferValue(bom + getString(), out);
+ }
+
+ public void testDecodeCharBufferByteBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ getUnmappedByteBuffer(), true);
+ }
+
+ public void testDecodeCharBufferByteIncompleteBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ getUnmappedByteBuffer(), false);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ readOnly(getUnmappedByteBuffer()), true);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyIncompleteBufferUnmappedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferUnmappedException(
+ readOnly(getUnmappedByteBuffer()), false);
+ }
+
+ void implTestDecodeCharBufferByteBufferUnmappedException(ByteBuffer in,
+ boolean endOfInput) throws CharacterCodingException,
+ UnsupportedEncodingException {
+ if (null == in) {
+ return;
+ }
+ CharBuffer out = CharBuffer.allocate(50);
+
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ decoder.reset();
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ CoderResult result = decoder.decode(in, out, endOfInput);
+ assertTrue(result.isUnmappable());
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(decoder.replacement() + getString(), out);
+ }
+
+ public void testDecodeCharBufferByteBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferMalformedException(
+ getMalformedByteBuffer(), true);
+ }
+
+ public void testDecodeCharBufferByteIncompleteBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+
+ implTestDecodeCharBufferByteBufferMalformedException(
+ getMalformedByteBuffer(), false);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferMalformedException(
+ readOnly(getMalformedByteBuffer()), true);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyIncompleteBufferMalformedException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferMalformedException(
+ readOnly(getMalformedByteBuffer()), false);
+ }
+
+ void implTestDecodeCharBufferByteBufferMalformedException(ByteBuffer in,
+ boolean endOfInput) throws CharacterCodingException,
+ UnsupportedEncodingException {
+ if (null == in) {
+ return;
+ }
+ CharBuffer out = CharBuffer.allocate(getString().length() * 3);
+ decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+ decoder.reset();
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+ CoderResult result = decoder.decode(in, out, endOfInput);
+ assertTrue(result.isMalformed());
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.IGNORE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(getString(), out);
+
+ decoder.reset();
+ out.clear();
+ in.rewind();
+ decoder.onMalformedInput(CodingErrorAction.REPLACE);
+ assertSame(CoderResult.UNDERFLOW, decoder.decode(in, out, endOfInput));
+ assertCharBufferValue(decoder.replacement() + getString(), out);
+ }
+
+ public void testDecodeCharBufferByteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
+ true);
+ }
+
+ public void testDecodeCharBufferByteIncompleteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(getExceptionByteArray(),
+ false);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(
+ readOnly(getExceptionByteArray()), true);
+ }
+
+ public void testDecodeCharBufferByteReadOnlyIncompleteBufferException()
+ throws CharacterCodingException, UnsupportedEncodingException {
+ implTestDecodeCharBufferByteBufferException(
+ readOnly(getExceptionByteArray()), false);
+ }
+
+ void implTestDecodeCharBufferByteBufferException(ByteBuffer in,
+ boolean endOfInput) throws CharacterCodingException,
+ UnsupportedEncodingException {
+ CharBuffer out = CharBuffer.allocate(50);
+ decoder.reset();
+ try {
+ decoder.decode(in, out, endOfInput);
+ fail("should throw runtime exception");
+ } catch (RuntimeException e) {
+ }
+ }
+
+ private ByteBuffer readOnly(ByteBuffer b) {
+ if (null == b) {
+ return null;
+ }
+ return b.asReadOnlyBuffer();
+ }
+
+ protected String getString() {
+ return " buffer";
+ }
+
+ protected ByteBuffer getByteBuffer() {
+ return ByteBuffer.wrap(new byte[] { 32, 98, 117, 102, 102, 101, 114 });
+ }
+
+ protected ByteBuffer getHeadlessByteBuffer() {
+ return getByteBuffer();
+ }
+
+ ByteBuffer getExceptionByteArray() throws UnsupportedEncodingException {
+ // "runtime"
+ return ByteBuffer
+ .wrap(new byte[] { 114, 117, 110, 116, 105, 109, 101 });
+ }
+
+ ByteBuffer getUnmappedByteBuffer() throws UnsupportedEncodingException {
+ // "unmap buffer"
+ byte[] ba = new byte[] { 117, 110, 109, 97, 112, 32, 98, 117, 102, 102,
+ 101, 114 };
+ return ByteBuffer.wrap(ba);
+ }
+
+ ByteBuffer getMalformedByteBuffer() throws UnsupportedEncodingException {
+ // "malform buffer"
+ byte[] ba = new byte[] { 109, 97, 108, 102, 111, 114, 109, 32, 98, 117,
+ 102, 102, 101, 114 };
+ return ByteBuffer.wrap(ba);
+ }
+
+ private void assertCharBufferValue(String expected, CharBuffer out) {
+ if (out.position() != 0) {
+ out.flip();
+ }
+ assertEquals(expected, new String(out.array(), out.arrayOffset(), out
+ .arrayOffset() + out.limit()));
+ }
+
+ /*
+ * test flush
+ */
+ public void testFlush() throws CharacterCodingException {
+ CharBuffer out = CharBuffer.allocate(10);
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 12, 12 });
+ decoder.decode(in, out, true);
+ assertSame(CoderResult.UNDERFLOW, decoder.flush(out));
+
+ decoder.reset();
+ decoder.decode((ByteBuffer) in.rewind(), (CharBuffer) out.rewind(),
+ true);
+ assertSame(CoderResult.UNDERFLOW, decoder
+ .flush(CharBuffer.allocate(10)));
+ }
+
+ /*
+ * ---------------------------------- methods to test illegal state
+ * -----------------------------------
+ */
+ // Normal case: just after reset, and it also means reset can be done
+ // anywhere
+ public void testResetIllegalState() throws CharacterCodingException {
+ decoder.reset();
+ decoder.decode(getByteBuffer());
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(3), false);
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(3), true);
+ decoder.reset();
+ }
+
+ public void testFlushIllegalState() throws CharacterCodingException {
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
+ CharBuffer out = CharBuffer.allocate(5);
+ // Normal case: after decode with endOfInput is true
+ decoder.reset();
+ decoder.decode(in, out, true);
+ out.rewind();
+ CoderResult result = decoder.flush(out);
+ assertSame(result, CoderResult.UNDERFLOW);
+
+ // Illegal state: flush twice
+ try {
+ decoder.flush(out);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ }
+
+ // Illegal state: flush after decode with endOfInput is false
+ decoder.reset();
+ decoder.decode(in, out, false);
+ try {
+ decoder.flush(out);
+ fail("should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ }
+ }
+
+ // test illegal states for decode facade
+ public void testDecodeFacadeIllegalState() throws CharacterCodingException {
+ // decode facade can be execute in anywhere
+ ByteBuffer in = getByteBuffer();
+
+ // Normal case: just created
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case: just after decode facade
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case: just after decode with that endOfInput is true
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case:just after decode with that endOfInput is false
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(30), false);
+ decoder.decode(in);
+ in.rewind();
+
+ // Normal case: just after flush
+ decoder.reset();
+ decoder.decode(getByteBuffer(), CharBuffer.allocate(30), true);
+ decoder.flush(CharBuffer.allocate(10));
+ decoder.decode(in);
+ in.rewind();
+ }
+
+ // test illegal states for two decode method with endOfInput is true
+ public void testDecodeTrueIllegalState() throws CharacterCodingException {
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
+ CharBuffer out = CharBuffer.allocate(100);
+ // Normal case: just created
+ decoder.decode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Normal case: just after decode with that endOfInput is true
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ in.rewind();
+ decoder.decode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Normal case:just after decode with that endOfInput is false
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), false);
+ in.rewind();
+ decoder.decode(in, out, true);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after flush
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ decoder.flush(CharBuffer.allocate(10));
+ in.rewind();
+ try {
+ decoder.decode(in, out, true);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ in.rewind();
+ out.rewind();
+
+ }
+
+ // test illegal states for two decode method with endOfInput is false
+ public void testDecodeFalseIllegalState() throws CharacterCodingException {
+ ByteBuffer in = ByteBuffer.wrap(new byte[] { 98, 98 });
+ CharBuffer out = CharBuffer.allocate(5);
+ // Normal case: just created
+ decoder.decode(in, out, false);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after decode facade
+ decoder.reset();
+ decoder.decode(in);
+ in.rewind();
+ try {
+ decoder.decode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after decode with that endOfInput is true
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ in.rewind();
+ try {
+ decoder.decode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ in.rewind();
+ out.rewind();
+
+ // Normal case:just after decode with that endOfInput is false
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), false);
+ in.rewind();
+ decoder.decode(in, out, false);
+ in.rewind();
+ out.rewind();
+
+ // Illegal state: just after flush
+ decoder.reset();
+ decoder.decode(in, CharBuffer.allocate(30), true);
+ in.rewind();
+ decoder.flush(CharBuffer.allocate(10));
+ try {
+ decoder.decode(in, out, false);
+ fail("should illegal state");
+ } catch (IllegalStateException e) {
+ }
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_TestGenerator_Res.java b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_TestGenerator_Res.java
index dfdffa6..a8c89ef 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_TestGenerator_Res.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_TestGenerator_Res.java
@@ -15,20 +15,9 @@
*/
package tests.api.java.nio.charset;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
-import junit.framework.TestCase;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CodingErrorAction;
-import java.util.Arrays;
/**
* Super class for concrete charset test suites.
diff --git a/openssl/src/main/java/org/openssl/NativeBN.java b/openssl/src/main/java/org/openssl/NativeBN.java
index 44464e0..fd796f8 100644
--- a/openssl/src/main/java/org/openssl/NativeBN.java
+++ b/openssl/src/main/java/org/openssl/NativeBN.java
@@ -79,9 +79,6 @@
public static native int[] bn2litEndInts(int a, int[] to);
- public static native byte[] bn2twosComp(int a, byte[] to);
-
-
public static native int sign(int a);
// Returns -1, 0, 1 AND NOT boolean.
// #define BN_is_negative(a) ((a)->neg != 0)
@@ -89,9 +86,6 @@
public static native void BN_set_negative(int b, int n);
// void BN_set_negative(BIGNUM *b, int n);
-
- public static native boolean twosCompFitsIntoBytes(int a, int byteCnt);
-
public static native int bitLength(int a);
public static native boolean BN_is_bit_set(int a, int n);
diff --git a/openssl/src/main/native/BNInterface.c b/openssl/src/main/native/BNInterface.c
index 4132e4f..79f0680 100644
--- a/openssl/src/main/native/BNInterface.c
+++ b/openssl/src/main/native/BNInterface.c
@@ -33,12 +33,6 @@
static void
-throwOutOfMemoryException(JNIEnv* env, const char* message)
-{
- jniThrowException(env, "java/lang/OutOfMemoryError", message);
-}
-
-static void
throwNewNullPointerException (JNIEnv* env, const char* message)
{
jniThrowException(env, "java/lang/NullPointerException", message);
@@ -456,27 +450,6 @@
}
}
-/**
- * public static native byte[] bn2twosComp(int, byte[])
- */
-static jbyteArray NativeBN_bn2twosComp(JNIEnv* env, jclass cls, BIGNUM* a, jbyteArray to) {
- if (!oneValidHandle(env, a)) return NULL;
- jbyteArray returnJBytes = to;
- unsigned char * tmpBytes;
- int len, byteCnt;
- byteCnt = BN_num_bytes(a);
-// FIXME: Currently ignoring array passed in to:
- returnJBytes = (*env)->NewByteArray(env, byteCnt);
-// FIXME: is it neccessary to check for returnJBytes != NULL?
- tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, returnJBytes, NULL));
- if (tmpBytes != NULL) {
- len = BN_bn2bin(a, tmpBytes);
- (*env)->ReleasePrimitiveArrayCritical(env, returnJBytes, tmpBytes, 0);
- return returnJBytes;
- }
- else return NULL;
-}
-
/**
* public static native int sign(int)
@@ -496,60 +469,6 @@
BN_set_negative(b, n);
}
-
-/**
- * public static native int twosCompFitsIntoBytes(int, int)
- */
-static jboolean NativeBN_twosCompFitsIntoBytes(JNIEnv* env, jclass cls, BIGNUM* a, int byteCnt) {
-// byteCnt IN {1, 2, 4, 8, 12, 16, ... (k * 4)}
-// We rely on: (BN_BITS2 == 32), i.e. BN_ULONG is unsigned int and has 4 bytes:
-//
-// LOGD("NativeBN_twosCompFitsIntoBytes");
- if (!oneValidHandle(env, a)) return FALSE;
- bn_check_top(a);
- int intLen = a->top;
- BN_ULONG* d = a->d;
- BN_ULONG msd; // most significant digit
- switch (byteCnt) {
- case 1:
- if (intLen > 1) return FALSE;
- else if (intLen == 0) return TRUE;
- msd = d[0];
- if (a->neg) msd--;
- return ((msd & 0XFFFFFF80) == 0);
- case 2:
- if (intLen > 1) return FALSE;
- else if (intLen == 0) return TRUE;
- msd = d[0];
- if (a->neg) msd--;
- return ((msd & 0XFFFF8000) == 0);
- case 4:
- if (intLen > 1) return FALSE;
- else if (intLen == 0) return TRUE;
- msd = d[0];
- if (a->neg) msd--;
- return ((msd & 0X80000000) == 0);
- case 8:
- if (intLen > 2) return FALSE;
- else if (intLen == 0) return TRUE;
- msd = d[1];
- if ((a->neg) && (d[0]) == 0) msd--;
- return ((msd & 0X80000000) == 0);
- default:
- if (intLen > byteCnt / 4) return FALSE;
- else if (intLen == 0) return TRUE;
- int i = intLen - 1;
- msd = d[i];
- if (a->neg) {
- // Handle negative values correctly:
- // i.e. decrement the msd if all other digits are 0:
- do { i--; } while (!((i < 0) || (d[i] != 0)));
- if (i < 0) msd--; // Only if all lower significant digits are 0 we decrement the most significant one.
- }
- return ((msd & 0X80000000) == 0);
- }
-}
-
/**
* public static native int bitLength(int)
*/
@@ -574,15 +493,6 @@
}
/**
- * public static native int BN_num_bits(int)
- */
-// static int NativeBN_BN_num_bits(JNIEnv* env, jclass cls, BIGNUM* a) {
-// LOGD("NativeBN_BN_num_bits");
-// if (!oneValidHandle(env, a)) return FALSE;
-// return BN_num_bits(a);
-// }
-
-/**
* public static native boolean BN_is_bit_set(int, int)
*/
static jboolean NativeBN_BN_is_bit_set(JNIEnv* env, jclass cls, BIGNUM* a, int n) {
@@ -833,12 +743,9 @@
{ "BN_bn2hex", "(I)Ljava/lang/String;", (void*)NativeBN_BN_bn2hex },
{ "BN_bn2bin", "(I[B)[B", (void*)NativeBN_BN_bn2bin },
{ "bn2litEndInts", "(I[I)[I", (void*)NativeBN_bn2litEndInts },
- { "bn2twosComp", "(I[B)[B", (void*)NativeBN_bn2twosComp },
{ "sign", "(I)I", (void*)NativeBN_sign },
{ "BN_set_negative", "(II)V", (void*)NativeBN_BN_set_negative },
- { "twosCompFitsIntoBytes", "(II)Z", (void*)NativeBN_twosCompFitsIntoBytes },
{ "bitLength", "(I)I", (void*)NativeBN_bitLength },
-// { "BN_num_bits", "(I)I", (void*)NativeBN_BN_num_bits },
{ "BN_is_bit_set", "(II)Z", (void*)NativeBN_BN_is_bit_set },
{ "modifyBit", "(III)Z", (void*)NativeBN_modifyBit },
{ "BN_lshift", "(III)Z", (void*)NativeBN_BN_lshift },
@@ -860,19 +767,6 @@
{ "BN_is_prime_ex", "(IIII)Z", (void*)NativeBN_BN_is_prime_ex }
};
-/*
- * Peforms the actual registration of the native methods.
- * Also looks up the fields that belong to the class (if
- * any) and stores the field IDs.
- */
int register_org_openssl_NativeBN(JNIEnv* env) {
-/*
- jclass clazz;
-
- clazz = (*env)->FindClass(env, "org/openssl/NativeBN");
- if (clazz == NULL) {
- return -1;
- }
-*/
return jniRegisterNativeMethods(env, "org/openssl/NativeBN", METHODS, NELEM(METHODS));
}
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java
index 76ef4e7..b45a75a 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java
@@ -16,12 +16,12 @@
package org.apache.harmony.prefs.tests.java.util.prefs;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
-
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
import junit.framework.TestCase;
+import tests.util.TestEnvironment;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -35,13 +35,9 @@
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
-import tests.util.PrefsTester;
-
@TestTargetClass(AbstractPreferences.class)
public class AbstractPreferencesTest extends TestCase {
- private final PrefsTester prefsTester = new PrefsTester();
-
AbstractPreferences pref;
static AbstractPreferences root;
@@ -55,7 +51,7 @@
protected void setUp() throws Exception {
super.setUp();
- prefsTester.setUp();
+ TestEnvironment.reset();
root = (AbstractPreferences) Preferences.userRoot();
parent = (AbstractPreferences) Preferences.userNodeForPackage(this.getClass());
@@ -64,7 +60,6 @@
}
protected void tearDown() throws Exception {
- prefsTester.tearDown();
super.tearDown();
}
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
index 0cb1975..4535a59 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
@@ -17,33 +17,29 @@
package org.apache.harmony.prefs.tests.java.util.prefs;
import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+import junit.framework.TestCase;
+import tests.util.TestEnvironment;
import java.io.FilePermission;
import java.security.Permission;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
-import junit.framework.TestCase;
-import tests.util.PrefsTester;
-
@TestTargetClass(java.util.prefs.Preferences.class)
public class FilePreferencesImplTest extends TestCase {
- private final PrefsTester prefsTester = new PrefsTester();
-
@Override
protected void setUp() throws Exception {
super.setUp();
- prefsTester.setUp();
+ TestEnvironment.reset();
}
@Override
protected void tearDown() throws Exception {
- prefsTester.tearDown();
super.tearDown();
}
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java
index 1afd755..e24026c 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java
@@ -16,10 +16,12 @@
package org.apache.harmony.prefs.tests.java.util.prefs;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.util.TestEnvironment;
import java.io.NotSerializableException;
import java.util.prefs.AbstractPreferences;
@@ -27,28 +29,20 @@
import java.util.prefs.NodeChangeEvent;
import java.util.prefs.Preferences;
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-import tests.util.PrefsTester;
-
/**
*
*/
@TestTargetClass(NodeChangeEvent.class)
public class NodeChangeEventTest extends TestCase {
- private final PrefsTester prefsTester = new PrefsTester();
-
NodeChangeEvent event;
protected void setUp() throws Exception {
super.setUp();
- prefsTester.setUp();
+ TestEnvironment.reset();
}
protected void tearDown() throws Exception {
- prefsTester.tearDown();
super.tearDown();
}
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeListenerTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeListenerTest.java
index 3cdb4d9..8e01589 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeListenerTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeListenerTest.java
@@ -16,26 +16,22 @@
package org.apache.harmony.prefs.tests.java.util.prefs;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import junit.framework.TestCase;
+import tests.util.TestEnvironment;
import java.util.prefs.NodeChangeEvent;
import java.util.prefs.NodeChangeListener;
import java.util.prefs.Preferences;
-import junit.framework.TestCase;
-import tests.util.PrefsTester;
-
/**
*
*/
@TestTargetClass(NodeChangeListener.class)
public class NodeChangeListenerTest extends TestCase {
- private final PrefsTester prefsTester = new PrefsTester();
-
NodeChangeListener l;
/*
@@ -44,7 +40,7 @@
@Override
protected void setUp() throws Exception {
super.setUp();
- prefsTester.setUp();
+ TestEnvironment.reset();
l = new NodeChangeListenerImpl();
}
@@ -53,7 +49,6 @@
*/
@Override
protected void tearDown() throws Exception {
- prefsTester.tearDown();
super.tearDown();
}
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferenceChangeEventTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferenceChangeEventTest.java
index dda1f6c..47e621e 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferenceChangeEventTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferenceChangeEventTest.java
@@ -16,20 +16,18 @@
package org.apache.harmony.prefs.tests.java.util.prefs;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import junit.framework.TestCase;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.util.TestEnvironment;
import java.io.NotSerializableException;
import java.util.prefs.AbstractPreferences;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.Preferences;
-import junit.framework.TestCase;
-
-import org.apache.harmony.testframework.serialization.SerializationTest;
-
/**
*
*/
@@ -38,6 +36,15 @@
PreferenceChangeEvent event;
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
+ @Override protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Checks exception.",
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
index c9c74fd..122dacd 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
@@ -21,11 +21,10 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
-
import junit.framework.TestCase;
+import tests.util.TestEnvironment;
import java.io.ByteArrayInputStream;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -39,16 +38,12 @@
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
-import tests.util.PrefsTester;
-
/**
*
*/
@TestTargetClass(Preferences.class)
public class PreferencesTest extends TestCase {
- private final PrefsTester prefsTester = new PrefsTester();
-
MockSecurityManager manager = new MockSecurityManager();
MockInputStream stream = null;
@@ -82,7 +77,7 @@
"<!DOCTYPE preferences SYSTEM \"http://java.sun.com/dtd/preferences.dtd\"><preferences><root type=\"user\"><map></map></root></preferences>"
.getBytes("UTF-8"));
stream = new MockInputStream(in);
- prefsTester.setUp();
+ TestEnvironment.reset();
}
/*
@@ -91,7 +86,6 @@
@Override
protected void tearDown() throws Exception {
stream.close();
- prefsTester.tearDown();
super.tearDown();
}
diff --git a/regex/src/main/java/java/util/regex/MatchResult.java b/regex/src/main/java/java/util/regex/MatchResult.java
index fa67ba6..76c17a8 100644
--- a/regex/src/main/java/java/util/regex/MatchResult.java
+++ b/regex/src/main/java/java/util/regex/MatchResult.java
@@ -1,17 +1,18 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package java.util.regex;
@@ -22,91 +23,75 @@
* pair of parentheses in the regular expression and an additional group for
* the whole regular expression. The start, end, and contents of each group
* can be queried.
- *
+ *
* @see Matcher
* @see Matcher#toMatchResult()
- *
- * @since Android 1.0
*/
public interface MatchResult {
/**
* Returns the index of the first character following the text that matched
- * the whole regular expression.
- *
+ * the whole regular expression.
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int end();
/**
* Returns the index of the first character following the text that matched
* a given group.
- *
+ *
* @param group
* the group, ranging from 0 to groupCount() - 1, with 0
* representing the whole pattern.
- *
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int end(int group);
/**
- * Returns the text that matched the whole regular expression.
- *
+ * Returns the text that matched the whole regular expression.
+ *
* @return the text.
- *
- * @since Android 1.0
*/
String group();
/**
* Returns the text that matched a given group of the regular expression.
- *
+ *
* @param group
* the group, ranging from 0 to groupCount() - 1, with 0
* representing the whole pattern.
- *
+ *
* @return the text that matched the group.
- *
- * @since Android 1.0
*/
String group(int group);
/**
* Returns the number of groups in the result, which is always equal to
* the number of groups in the original regular expression.
- *
+ *
* @return the number of groups.
- *
- * @since Android 1.0
*/
int groupCount();
/**
* Returns the index of the first character of the text that matched
- * the whole regular expression.
- *
+ * the whole regular expression.
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int start();
/**
* Returns the index of the first character of the text that matched a given
* group.
- *
+ *
* @param group
* the group, ranging from 0 to groupCount() - 1, with 0
* representing the whole pattern.
- *
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int start(int group);
}
diff --git a/regex/src/main/java/java/util/regex/Matcher.java b/regex/src/main/java/java/util/regex/Matcher.java
index e3e4874..be5c782 100644
--- a/regex/src/main/java/java/util/regex/Matcher.java
+++ b/regex/src/main/java/java/util/regex/Matcher.java
@@ -44,8 +44,6 @@
* {@code Pattern} was successful and at which position the next attempt would
* resume the search. Depending on the application's needs, it may become
* necessary to explicitly {@link #reset()} this state from time to time.
- *
- * @since Android 1.0
*/
public final class Matcher implements MatchResult {
@@ -128,39 +126,99 @@
}
/**
+ * Appends a literal part of the input plus a replacement for the current
+ * match to a given {@link StringBuffer}. The literal part is exactly the
+ * part of the input between the previous match and the current match. The
+ * method can be used in conjunction with {@link #find()} and
+ * {@link #appendTail(StringBuffer)} to walk through the input and replace
+ * all occurrences of the {@code Pattern} with something else.
+ *
+ * @param buffer
+ * the {@code StringBuffer} to append to.
+ * @param replacement
+ * the replacement text.
+ * @return the {@code Matcher} itself.
+ * @throws IllegalStateException
+ * if no successful match has been made.
+ */
+ public Matcher appendReplacement(StringBuffer buffer, String replacement) {
+ buffer.append(input.substring(appendPos, start()));
+ appendEvaluated(buffer, replacement);
+ appendPos = end();
+
+ return this;
+ }
+
+ /**
+ * Internal helper method to append a given string to a given string buffer.
+ * If the string contains any references to groups, these are replaced by
+ * the corresponding group's contents.
+ *
+ * @param buffer
+ * the string buffer.
+ * @param s
+ * the string to append.
+ */
+ private void appendEvaluated(StringBuffer buffer, String s) {
+ boolean escape = false;
+ boolean dollar = false;
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' && !escape) {
+ escape = true;
+ } else if (c == '$' && !escape) {
+ dollar = true;
+ } else if (c >= '0' && c <= '9' && dollar) {
+ buffer.append(group(c - '0'));
+ dollar = false;
+ } else {
+ buffer.append(c);
+ dollar = false;
+ escape = false;
+ }
+ }
+
+ // This seemingly stupid piece of code reproduces a JDK bug.
+ if (escape) {
+ throw new ArrayIndexOutOfBoundsException(s.length());
+ }
+ }
+
+ /**
* Resets the Matcher. A new input sequence and a new region can be
* specified. Results of a previous find get lost. The next attempt to find
* an occurrence of the Pattern in the string will start at the beginning of
* the region. This is the internal version of reset() to which the several
* public versions delegate.
- *
+ *
* @param input
* the input sequence.
* @param start
* the start of the region.
* @param end
* the end of the region.
- *
+ *
* @return the matcher itself.
*/
private Matcher reset(CharSequence input, int start, int end) {
if (input == null) {
throw new IllegalArgumentException();
}
-
- if (start < 0 || end < 0 || start > input.length() ||
+
+ if (start < 0 || end < 0 || start > input.length() ||
end > input.length() || start > end) {
throw new IllegalArgumentException();
}
// Maybe should have a reset() here, but it makes thing worse...
// NativeRegEx.reset(nativePattern, 0);
-
+
if (!input.equals(this.input)) {
this.input = input.toString();
-
+
NativeRegEx.setText(nativePattern, this.input);
-
+
regionStart = 0;
regionEnd = input.length();
}
@@ -176,22 +234,8 @@
matchFound = false;
findPos = regionStart;
appendPos = 0;
-
- return this;
- }
- /**
- * Resets the {@code Matcher}. This results in the region being set to the
- * whole input. Results of a previous find get lost. The next attempt to
- * find an occurrence of the {@link Pattern} in the string will start at the
- * beginning of the input.
- *
- * @return the {@code Matcher} itself.
- *
- * @since Android 1.0
- */
- public Matcher reset() {
- return reset(input, 0, input.length());
+ return this;
}
/**
@@ -204,73 +248,24 @@
* the new input sequence.
*
* @return the {@code Matcher} itself.
- *
- * @since Android 1.0
*/
public Matcher reset(CharSequence input) {
return reset(input, 0, input.length());
}
/**
- * Sets a new pattern for the {@code Matcher}. Results of a previous find
- * get lost. The next attempt to find an occurrence of the {@link Pattern}
- * in the string will start at the beginning of the input.
- *
- * @param pattern
- * the new {@code Pattern}.
- *
+ * Resets the {@code Matcher}. This results in the region being set to the
+ * whole input. Results of a previous find get lost. The next attempt to
+ * find an occurrence of the {@link Pattern} in the string will start at the
+ * beginning of the input.
+ *
* @return the {@code Matcher} itself.
- *
- * @since Android 1.0
*/
- public Matcher usePattern(Pattern pattern) {
- if (pattern == null) {
- throw new IllegalArgumentException();
- }
-
- this.pattern = pattern;
-
- if (nativePattern != 0) {
- NativeRegEx.close(nativePattern);
- }
- nativePattern = NativeRegEx.clone(pattern.mNativePattern);
-
- if (input != null) {
- NativeRegEx.setText(nativePattern, input);
- NativeRegEx.setRegion(nativePattern, regionStart, regionEnd);
- NativeRegEx.useAnchoringBounds(nativePattern, anchoringBounds);
- NativeRegEx.useTransparentBounds(nativePattern, transparentBounds);
- }
-
- matchOffsets = new int[(this.pattern.mGroupCount + 1) * 2];
- matchFound = false;
- return this;
+ public Matcher reset() {
+ return reset(input, 0, input.length());
}
/**
- * Returns the {@link Pattern} instance used inside this matcher.
- *
- * @return the {@code Pattern} instance.
- *
- * @since Android 1.0
- */
- public Pattern pattern() {
- return pattern;
- }
-
- /**
- * Returns the number of groups in the results, which is always equal to
- * the number of groups in the original regular expression.
- *
- * @return the number of groups.
- *
- * @since Android 1.0
- */
- public int groupCount() {
- return pattern.mGroupCount;
- }
-
- /**
* Resets this matcher and sets a region. Only characters inside the region
* are considered for a match.
*
@@ -279,109 +274,150 @@
* @param end
* the first character after the end of the region.
* @return the {@code Matcher} itself.
- * @since Android 1.0
*/
public Matcher region(int start, int end) {
return reset(input, start, end);
}
- /**
- * Returns this matcher's region start, that is, the first character that is
- * considered for a match.
- *
- * @return the start of the region.
- * @since Android 1.0
- */
- public int regionStart() {
- return regionStart;
- }
/**
- * Returns this matcher's region end, that is, the first character that is
- * not considered for a match.
- *
- * @return the end of the region.
- * @since Android 1.0
- */
- public int regionEnd() {
- return regionEnd;
- }
-
- /**
- * Determines whether this matcher has anchoring bounds enabled or not. When
- * anchoring bounds are enabled, the start and end of the input match the
- * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
- * by default.
- *
- * @param value
- * the new value for anchoring bounds.
- * @return the {@code Matcher} itself.
- * @since Android 1.0
- */
- public Matcher useAnchoringBounds(boolean value) {
- anchoringBounds = value;
- NativeRegEx.useAnchoringBounds(nativePattern, value);
- return this;
- }
-
- /**
- * Indicates whether this matcher has anchoring bounds enabled. When
- * anchoring bounds are enabled, the start and end of the input match the
- * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
- * by default.
- *
- * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
- * @since Android 1.0
- */
- public boolean hasAnchoringBounds() {
- return anchoringBounds;
- }
-
- /**
- * Determines whether this matcher has transparent bounds enabled or not.
- * When transparent bounds are enabled, the parts of the input outside the
- * region are subject to lookahead and lookbehind, otherwise they are not.
- * Transparent bounds are disabled by default.
- *
- * @param value
- * the new value for transparent bounds.
- * @return the {@code Matcher} itself.
- * @since Android 1.0
- */
- public Matcher useTransparentBounds(boolean value) {
- transparentBounds = value;
- NativeRegEx.useTransparentBounds(nativePattern, value);
- return this;
- }
-
- /**
- * Indicates whether this matcher has transparent bounds enabled. When
- * transparent bounds are enabled, the parts of the input outside the region
- * are subject to lookahead and lookbehind, otherwise they are not.
- * Transparent bounds are disabled by default.
- *
- * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
- * @since Android 1.0
- */
- public boolean hasTransparentBounds() {
- return transparentBounds;
- }
-
- /**
- * Makes sure that a successful match has been made. Is invoked internally
- * from various places in the class.
- *
+ * Appends the (unmatched) remainder of the input to the given
+ * {@link StringBuffer}. The method can be used in conjunction with
+ * {@link #find()} and {@link #appendReplacement(StringBuffer, String)} to
+ * walk through the input and replace all matches of the {@code Pattern}
+ * with something else.
+ *
+ * @param buffer
+ * the {@code StringBuffer} to append to.
+ * @return the {@code StringBuffer}.
* @throws IllegalStateException
* if no successful match has been made.
- *
- * @since Android 1.0
*/
- private void ensureMatch() throws IllegalStateException {
- if (!matchFound) {
- throw new IllegalStateException("No successful match so far");
+ public StringBuffer appendTail(StringBuffer buffer) {
+ if (appendPos < regionEnd) {
+ buffer.append(input.substring(appendPos, regionEnd));
+ }
+
+ return buffer;
+ }
+
+ /**
+ * Replaces the first occurrence of this matcher's pattern in the input with
+ * a given string.
+ *
+ * @param replacement
+ * the replacement text.
+ * @return the modified input string.
+ */
+ public String replaceFirst(String replacement) {
+ StringBuffer buffer = new StringBuffer(input.length());
+
+ findPos = 0;
+ appendPos = 0;
+ matchFound = false;
+ searching = false;
+
+ if (find()) {
+ appendReplacement(buffer, replacement);
+ }
+
+ return appendTail(buffer).toString();
+ }
+
+ /**
+ * Replaces all occurrences of this matcher's pattern in the input with a
+ * given string.
+ *
+ * @param replacement
+ * the replacement text.
+ * @return the modified input string.
+ */
+ public String replaceAll(String replacement) {
+ StringBuffer buffer = new StringBuffer(input.length());
+
+ findPos = 0;
+ appendPos = 0;
+ matchFound = false;
+ searching = false;
+
+ while (find()) {
+ appendReplacement(buffer, replacement);
+ }
+
+ return appendTail(buffer).toString();
+ }
+
+ /**
+ * Returns the {@link Pattern} instance used inside this matcher.
+ *
+ * @return the {@code Pattern} instance.
+ */
+ public Pattern pattern() {
+ return pattern;
+ }
+
+ /**
+ * Returns the text that matched a given group of the regular expression.
+ *
+ * @param group
+ * the group, ranging from 0 to groupCount() - 1, with 0
+ * representing the whole pattern.
+ * @return the text that matched the group.
+ * @throws IllegalStateException
+ * if no successful match has been made.
+ */
+ public String group(int group) {
+ ensureMatch();
+ int from = matchOffsets[group * 2];
+ int to = matchOffsets[(group * 2) + 1];
+ if (from == -1 || to == -1) {
+ return null;
+ } else {
+ return input.substring(from, to);
}
}
-
+
+ /**
+ * Returns the text that matched the whole regular expression.
+ *
+ * @return the text.
+ * @throws IllegalStateException
+ * if no successful match has been made.
+ */
+ public String group() {
+ return group(0);
+ }
+
+ /**
+ * Returns the next occurrence of the {@link Pattern} in the input. The
+ * method starts the search from the given character in the input.
+ *
+ * @param start
+ * The index in the input at which the find operation is to
+ * begin. If this is less than the start of the region, it is
+ * automatically adjusted to that value. If it is beyond the end
+ * of the region, the method will fail.
+ * @return true if (and only if) a match has been found.
+ */
+ public boolean find(int start) {
+ findPos = start;
+
+ if (findPos < regionStart) {
+ findPos = regionStart;
+ } else if (findPos >= regionEnd) {
+ matchFound = false;
+ return false;
+ }
+
+ matchFound = NativeRegEx.find(nativePattern, findPos);
+ if (matchFound) {
+ NativeRegEx.startEnd(nativePattern, matchOffsets);
+ findPos = matchOffsets[1];
+ }
+
+ return matchFound;
+ }
+
/**
* Returns the next occurrence of the {@link Pattern} in the input. If a
* previous match was successful, the method continues the search from the
@@ -389,7 +425,6 @@
* either from the region start (if one has been set), or from position 0.
*
* @return true if (and only if) a match has been found.
- * @since Android 1.0
*/
public boolean find() {
if (!searching) {
@@ -408,34 +443,35 @@
}
/**
- * Returns the next occurrence of the {@link Pattern} in the input. The
- * method starts the search from the given character in the input.
- *
- * @param start
- * The index in the input at which the find operation is to
- * begin. If this is less than the start of the region, it is
- * automatically adjusted to that value. If it is beyond the end
- * of the region, the method will fail.
- * @return true if (and only if) a match has been found.
- * @since Android 1.0
+ * Returns the index of the first character of the text that matched a given
+ * group.
+ *
+ * @param group
+ * the group, ranging from 0 to groupCount() - 1, with 0
+ * representing the whole pattern.
+ * @return the character index.
+ * @throws IllegalStateException
+ * if no successful match has been made.
*/
- public boolean find(int start) {
- findPos = start;
-
- if (findPos < regionStart) {
- findPos = regionStart;
- } else if (findPos >= regionEnd) {
- matchFound = false;
- return false;
- }
-
- matchFound = NativeRegEx.find(nativePattern, findPos);
- if (matchFound) {
- NativeRegEx.startEnd(nativePattern, matchOffsets);
- findPos = matchOffsets[1];
- }
-
- return matchFound;
+ public int start(int group) throws IllegalStateException {
+ ensureMatch();
+ return matchOffsets[group * 2];
+ }
+
+ /**
+ * Returns the index of the first character following the text that matched
+ * a given group.
+ *
+ * @param group
+ * the group, ranging from 0 to groupCount() - 1, with 0
+ * representing the whole pattern.
+ * @return the character index.
+ * @throws IllegalStateException
+ * if no successful match has been made.
+ */
+ public int end(int group) {
+ ensureMatch();
+ return matchOffsets[(group * 2) + 1];
}
/**
@@ -444,8 +480,6 @@
*
* @return true if (and only if) the {@code Pattern} matches the entire
* region.
- *
- * @since Android 1.0
*/
public boolean matches() {
matchFound = NativeRegEx.matches(nativePattern, -1);
@@ -458,13 +492,34 @@
}
/**
+ * Returns a replacement string for the given one that has all backslashes
+ * and dollar signs escaped.
+ *
+ * @param s
+ * the input string.
+ * @return the input string, with all backslashes and dollar signs having
+ * been escaped.
+ */
+ public static String quoteReplacement(String s) {
+ StringBuffer buffer = new StringBuffer(s.length());
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' || c == '$') {
+ buffer.append('\\');
+ }
+ buffer.append(c);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
* Tries to match the {@link Pattern}, starting from the beginning of the
* region (or the beginning of the input, if no region has been set).
* Doesn't require the {@code Pattern} to match against the whole region.
*
* @return true if (and only if) the {@code Pattern} matches.
- *
- * @since Android 1.0
*/
public boolean lookingAt() {
matchFound = NativeRegEx.lookingAt(nativePattern, -1);
@@ -483,27 +538,19 @@
* @return the character index.
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
- public int start() throws IllegalStateException {
+ public int start() {
return start(0);
}
/**
- * Returns the index of the first character of the text that matched a given
- * group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the character index.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
+ * Returns the number of groups in the results, which is always equal to
+ * the number of groups in the original regular expression.
+ *
+ * @return the number of groups.
*/
- public int start(int group) throws IllegalStateException {
- ensureMatch();
- return matchOffsets[group * 2];
+ public int groupCount() {
+ return pattern.mGroupCount;
}
/**
@@ -513,94 +560,19 @@
* @return the character index.
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
public int end() {
return end(0);
}
/**
- * Returns the index of the first character following the text that matched
- * a given group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the character index.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
- */
- public int end(int group) {
- ensureMatch();
- return matchOffsets[(group * 2) + 1];
- }
-
- /**
- * Returns the text that matched the whole regular expression.
- *
- * @return the text.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
- */
- public String group() {
- return group(0);
- }
-
- /**
- * Returns the text that matched a given group of the regular expression.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the text that matched the group.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
- */
- public String group(int group) {
- ensureMatch();
- int from = matchOffsets[group * 2];
- int to = matchOffsets[(group * 2) + 1];
- if (from == -1 || to == -1) {
- return null;
- } else {
- return input.substring(from, to);
- }
- }
-
- /**
- * Indicates whether the last match hit the end of the input.
- *
- * @return true if (and only if) the last match hit the end of the input.
- * @since Android 1.0
- */
- public boolean hitEnd() {
- return NativeRegEx.hitEnd(nativePattern);
- }
-
- /**
- * Indicates whether more input might change a successful match into an
- * unsuccessful one.
- *
- * @return true if (and only if) more input might change a successful match
- * into an unsuccessful one.
- * @since Android 1.0
- */
- public boolean requireEnd() {
- return NativeRegEx.requireEnd(nativePattern);
- }
-
- /**
* Converts the current match into a separate {@link MatchResult} instance
* that is independent from this matcher. The new object is unaffected when
* the state of this matcher changes.
- *
+ *
* @return the new {@code MatchResult}.
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
public MatchResult toMatchResult() {
ensureMatch();
@@ -608,160 +580,146 @@
}
/**
- * Appends a literal part of the input plus a replacement for the current
- * match to a given {@link StringBuffer}. The literal part is exactly the
- * part of the input between the previous match and the current match. The
- * method can be used in conjunction with {@link #find()} and
- * {@link #appendTail(StringBuffer)} to walk through the input and replace
- * all occurrences of the {@code Pattern} with something else.
- *
- * @param buffer
- * the {@code StringBuffer} to append to.
- * @param replacement
- * the replacement text.
+ * Determines whether this matcher has anchoring bounds enabled or not. When
+ * anchoring bounds are enabled, the start and end of the input match the
+ * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
+ * by default.
+ *
+ * @param value
+ * the new value for anchoring bounds.
* @return the {@code Matcher} itself.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
*/
- public Matcher appendReplacement(StringBuffer buffer, String replacement)
- throws IllegalStateException {
-
- buffer.append(input.substring(appendPos, start()));
- appendEvaluated(buffer, replacement);
- appendPos = end();
-
+ public Matcher useAnchoringBounds(boolean value) {
+ anchoringBounds = value;
+ NativeRegEx.useAnchoringBounds(nativePattern, value);
return this;
}
/**
- * Appends the (unmatched) remainder of the input to the given
- * {@link StringBuffer}. The method can be used in conjunction with
- * {@link #find()} and {@link #appendReplacement(StringBuffer, String)} to
- * walk through the input and replace all matches of the {@code Pattern}
- * with something else.
- *
- * @param buffer
- * the {@code StringBuffer} to append to.
- * @return the {@code StringBuffer}.
+ * Indicates whether this matcher has anchoring bounds enabled. When
+ * anchoring bounds are enabled, the start and end of the input match the
+ * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
+ * by default.
+ *
+ * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
+ */
+ public boolean hasAnchoringBounds() {
+ return anchoringBounds;
+ }
+
+ /**
+ * Determines whether this matcher has transparent bounds enabled or not.
+ * When transparent bounds are enabled, the parts of the input outside the
+ * region are subject to lookahead and lookbehind, otherwise they are not.
+ * Transparent bounds are disabled by default.
+ *
+ * @param value
+ * the new value for transparent bounds.
+ * @return the {@code Matcher} itself.
+ */
+ public Matcher useTransparentBounds(boolean value) {
+ transparentBounds = value;
+ NativeRegEx.useTransparentBounds(nativePattern, value);
+ return this;
+ }
+
+ /**
+ * Makes sure that a successful match has been made. Is invoked internally
+ * from various places in the class.
+ *
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
- public StringBuffer appendTail(StringBuffer buffer) {
- if (appendPos < regionEnd) {
- buffer.append(input.substring(appendPos, regionEnd));
+ private void ensureMatch() {
+ if (!matchFound) {
+ throw new IllegalStateException("No successful match so far");
}
-
- return buffer;
}
/**
- * Internal helper method to append a given string to a given string buffer.
- * If the string contains any references to groups, these are replaced by
- * the corresponding group's contents.
- *
- * @param buffer
- * the string buffer.
- * @param s
- * the string to append.
+ * Indicates whether this matcher has transparent bounds enabled. When
+ * transparent bounds are enabled, the parts of the input outside the region
+ * are subject to lookahead and lookbehind, otherwise they are not.
+ * Transparent bounds are disabled by default.
+ *
+ * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
*/
- private void appendEvaluated(StringBuffer buffer, String s) {
- boolean escape = false;
- boolean dollar = false;
-
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '\\' && !escape) {
- escape = true;
- } else if (c == '$' && !escape) {
- dollar = true;
- } else if (c >= '0' && c <= '9' && dollar) {
- buffer.append(group(c - '0'));
- dollar = false;
- } else {
- buffer.append(c);
- dollar = false;
- escape = false;
- }
- }
-
- // This seemingly stupid piece of code reproduces a JDK bug.
- if (escape) {
- throw new ArrayIndexOutOfBoundsException(s.length());
- }
+ public boolean hasTransparentBounds() {
+ return transparentBounds;
}
-
+
/**
- * Replaces all occurrences of this matcher's pattern in the input with a
- * given string.
- *
- * @param replacement
- * the replacement text.
- * @return the modified input string.
- * @since Android 1.0
+ * Returns this matcher's region start, that is, the first character that is
+ * considered for a match.
+ *
+ * @return the start of the region.
*/
- public String replaceAll(String replacement) {
- StringBuffer buffer = new StringBuffer(input.length());
-
- findPos = 0;
- appendPos = 0;
+ public int regionStart() {
+ return regionStart;
+ }
+
+ /**
+ * Returns this matcher's region end, that is, the first character that is
+ * not considered for a match.
+ *
+ * @return the end of the region.
+ */
+ public int regionEnd() {
+ return regionEnd;
+ }
+
+ /**
+ * Indicates whether more input might change a successful match into an
+ * unsuccessful one.
+ *
+ * @return true if (and only if) more input might change a successful match
+ * into an unsuccessful one.
+ */
+ public boolean requireEnd() {
+ return NativeRegEx.requireEnd(nativePattern);
+ }
+
+ /**
+ * Indicates whether the last match hit the end of the input.
+ *
+ * @return true if (and only if) the last match hit the end of the input.
+ */
+ public boolean hitEnd() {
+ return NativeRegEx.hitEnd(nativePattern);
+ }
+
+ /**
+ * Sets a new pattern for the {@code Matcher}. Results of a previous find
+ * get lost. The next attempt to find an occurrence of the {@link Pattern}
+ * in the string will start at the beginning of the input.
+ *
+ * @param pattern
+ * the new {@code Pattern}.
+ *
+ * @return the {@code Matcher} itself.
+ */
+ public Matcher usePattern(Pattern pattern) {
+ if (pattern == null) {
+ throw new IllegalArgumentException();
+ }
+
+ this.pattern = pattern;
+
+ if (nativePattern != 0) {
+ NativeRegEx.close(nativePattern);
+ }
+ nativePattern = NativeRegEx.clone(pattern.mNativePattern);
+
+ if (input != null) {
+ NativeRegEx.setText(nativePattern, input);
+ NativeRegEx.setRegion(nativePattern, regionStart, regionEnd);
+ NativeRegEx.useAnchoringBounds(nativePattern, anchoringBounds);
+ NativeRegEx.useTransparentBounds(nativePattern, transparentBounds);
+ }
+
+ matchOffsets = new int[(this.pattern.mGroupCount + 1) * 2];
matchFound = false;
- searching = false;
-
- while (find()) {
- appendReplacement(buffer, replacement);
- }
-
- return appendTail(buffer).toString();
- }
-
- /**
- * Replaces the first occurrence of this matcher's pattern in the input with
- * a given string.
- *
- * @param replacement
- * the replacement text.
- * @return the modified input string.
- * @since Android 1.0
- */
- public String replaceFirst(String replacement) {
- StringBuffer buffer = new StringBuffer(input.length());
-
- findPos = 0;
- appendPos = 0;
- matchFound = false;
- searching = false;
-
- if (find()) {
- appendReplacement(buffer, replacement);
- }
-
- return appendTail(buffer).toString();
- }
-
- /**
- * Returns a replacement string for the given one that has all backslashes
- * and dollar signs escaped.
- *
- * @param s
- * the input string.
- * @return the input string, with all backslashes and dollar signs having
- * been escaped.
- * @since Android 1.0
- */
- public static String quoteReplacement(String s) {
- StringBuffer buffer = new StringBuffer(s.length());
-
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '\\' || c == '$') {
- buffer.append('\\');
- }
- buffer.append(c);
- }
-
- return buffer.toString();
+ return this;
}
@Override
diff --git a/regex/src/main/java/java/util/regex/Pattern.java b/regex/src/main/java/java/util/regex/Pattern.java
index 2c71de1..db3bc21 100644
--- a/regex/src/main/java/java/util/regex/Pattern.java
+++ b/regex/src/main/java/java/util/regex/Pattern.java
@@ -47,7 +47,7 @@
* boolean b2 = Pattern.matches("Hello, A[a-z]*!", "Hello, Robot!"); // false
* </pre>
* <p/>
- * Please consult the <a href="package-summary.html">package documentation</a> for an
+ * Please consult the <a href="package.html">package documentation</a> for an
* overview of the regular expression syntax used in this class as well as
* Android-specific implementation details.
*
@@ -61,8 +61,6 @@
/**
* This constant specifies that a pattern matches Unix line endings ('\n')
* only against the '.', '^', and '$' meta characters.
- *
- * @since Android 1.0
*/
public static final int UNIX_LINES = 0x01;
@@ -76,8 +74,6 @@
* constant. So if case insensitivity is enabled, this automatically extends
* to all Unicode characters. The {@code UNICODE_CASE} constant itself has
* no special consequences.
- *
- * @since Android 1.0
*/
public static final int CASE_INSENSITIVE = 0x02;
@@ -85,8 +81,6 @@
* This constant specifies that a {@code Pattern} may contain whitespace or
* comments. Otherwise comments and whitespace are taken as literal
* characters.
- *
- * @since Android 1.0
*/
public static final int COMMENTS = 0x04;
@@ -94,24 +88,18 @@
* This constant specifies that the meta characters '^' and '$' match only
* the beginning and end end of an input line, respectively. Normally, they
* match the beginning and the end of the complete input.
- *
- * @since Android 1.0
*/
public static final int MULTILINE = 0x08;
/**
* This constant specifies that the whole {@code Pattern} is to be taken
* literally, that is, all meta characters lose their meanings.
- *
- * @since Android 1.0
*/
public static final int LITERAL = 0x10;
/**
* This constant specifies that the '.' meta character matches arbitrary
* characters, including line endings, which is normally not the case.
- *
- * @since Android 1.0
*/
public static final int DOTALL = 0x20;
@@ -126,8 +114,6 @@
* constant. So if case insensitivity is enabled, this automatically extends
* to all Unicode characters. The {@code UNICODE_CASE} constant then has no
* special consequences.
- *
- * @since Android 1.0
*/
public static final int UNICODE_CASE = 0x40;
@@ -135,8 +121,6 @@
* This constant specifies that a character in a {@code Pattern} and a
* character in the input string only match if they are canonically
* equivalent. It is (currently) not supported in Android.
- *
- * @since Android 1.0
*/
public static final int CANON_EQ = 0x80;
@@ -159,24 +143,144 @@
* Holds the number of groups in the pattern.
*/
transient int mGroupCount;
-
+
+
/**
- * Compiles a regular expression, creating a new Pattern instance in the
- * process. This is actually a convenience method that calls {@link
- * #compile(String, int)} with a {@code flags} value of zero.
- *
- * @param pattern
- * the regular expression.
- *
- * @return the new {@code Pattern} instance.
- *
- * @throws PatternSyntaxException
- * if the regular expression is syntactically incorrect.
- *
- * @since Android 1.0
+ * Returns a {@link Matcher} for the {@code Pattern} and a given input. The
+ * {@code Matcher} can be used to match the {@code Pattern} against the
+ * whole input, find occurrences of the {@code Pattern} in the input, or
+ * replace parts of the input.
+ *
+ * @param input
+ * the input to process.
+ *
+ * @return the resulting {@code Matcher}.
*/
- public static Pattern compile(String pattern) throws PatternSyntaxException {
- return new Pattern(pattern, 0);
+ public Matcher matcher(CharSequence input) {
+ return new Matcher(this, input);
+ }
+
+ /**
+ * Splits the given input sequence at occurrences of this {@code Pattern}.
+ *
+ * <p>If this {@code Pattern} does not occur in the input, the result is an
+ * array containing the input (converted from a {@code CharSequence} to
+ * a {@code String}).
+ *
+ * <p>Otherwise, the {@code limit} parameter controls the contents of the
+ * returned array as described below.
+ *
+ * @param inputSeq
+ * the input sequence.
+ * @param limit
+ * Determines the maximum number of entries in the resulting
+ * array, and the treatment of trailing empty strings.
+ * <ul>
+ * <li>For n > 0, the resulting array contains at most n
+ * entries. If this is fewer than the number of matches, the
+ * final entry will contain all remaining input.
+ * <li>For n < 0, the length of the resulting array is
+ * exactly the number of occurrences of the {@code Pattern}
+ * plus one for the text after the final separator.
+ * All entries are included.
+ * <li>For n == 0, the result is as for n < 0, except
+ * trailing empty strings will not be returned. (Note that
+ * the case where the input is itself an empty string is
+ * special, as described above, and the limit parameter does
+ * not apply there.)
+ * </ul>
+ *
+ * @return the resulting array.
+ */
+ public String[] split(CharSequence inputSeq, int limit) {
+ if (inputSeq.length() == 0) {
+ // Unlike Perl, which considers the result of splitting the empty
+ // string to be the empty array, Java returns an array containing
+ // the empty string.
+ return new String[] { "" };
+ }
+
+ int maxLength = limit <= 0 ? Integer.MAX_VALUE : limit;
+
+ String input = inputSeq.toString();
+ ArrayList<String> list = new ArrayList<String>();
+
+ Matcher matcher = new Matcher(this, inputSeq);
+ int savedPos = 0;
+
+ // Add text preceding each occurrence, if enough space.
+ while(matcher.find() && list.size() + 1 < maxLength) {
+ list.add(input.substring(savedPos, matcher.start()));
+ savedPos = matcher.end();
+ }
+
+ // Add trailing text if enough space.
+ if (list.size() < maxLength) {
+ if (savedPos < input.length()) {
+ list.add(input.substring(savedPos));
+ } else {
+ list.add("");
+ }
+ }
+
+ // Remove trailing empty matches in the limit == 0 case.
+ if (limit == 0) {
+ int i = list.size() - 1;
+ while (i >= 0 && "".equals(list.get(i))) {
+ list.remove(i);
+ i--;
+ }
+ }
+
+ return list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * Splits a given input around occurrences of a regular expression. This is
+ * a convenience method that is equivalent to calling the method
+ * {@link #split(java.lang.CharSequence, int)} with a limit of 0.
+ *
+ * @param input
+ * the input sequence.
+ *
+ * @return the resulting array.
+ */
+ public String[] split(CharSequence input) {
+ return split(input, 0);
+ }
+
+ /**
+ * Returns the regular expression that was compiled into this
+ * {@code Pattern}.
+ *
+ * @return the regular expression.
+ */
+ public String pattern() {
+ return pattern;
+ }
+
+ @Override
+ public String toString() {
+ return pattern;
+ }
+
+ /**
+ * Returns the flags that have been set for this {@code Pattern}.
+ *
+ * @return the flags that have been set. A combination of the constants
+ * defined in this class.
+ *
+ * @see #CANON_EQ
+ * @see #CASE_INSENSITIVE
+ * @see #COMMENTS
+ * @see #DOTALL
+ * @see #LITERAL
+ * @see #MULTILINE
+ * @see #UNICODE_CASE
+ * @see #UNIX_LINES
+ */
+ public int flags() {
+ return flags;
}
/**
@@ -208,8 +312,6 @@
* @see #MULTILINE
* @see #UNICODE_CASE
* @see #UNIX_LINES
- *
- * @since Android 1.0
*/
public static Pattern compile(String pattern, int flags) throws PatternSyntaxException {
return new Pattern(pattern, flags);
@@ -238,7 +340,24 @@
compileImpl(pattern, flags);
}
-
+
+ /**
+ * Compiles a regular expression, creating a new Pattern instance in the
+ * process. This is actually a convenience method that calls {@link
+ * #compile(String, int)} with a {@code flags} value of zero.
+ *
+ * @param pattern
+ * the regular expression.
+ *
+ * @return the new {@code Pattern} instance.
+ *
+ * @throws PatternSyntaxException
+ * if the regular expression is syntactically incorrect.
+ */
+ public static Pattern compile(String pattern) {
+ return new Pattern(pattern, 0);
+ }
+
/**
* Compiles the given regular expression using the given flags. Used
* internally only.
@@ -266,56 +385,6 @@
}
/**
- * Returns the regular expression that was compiled into this
- * {@code Pattern}.
- *
- * @return the regular expression.
- *
- * @since Android 1.0
- */
- public String pattern() {
- return pattern;
- }
-
- /**
- * Returns the flags that have been set for this {@code Pattern}.
- *
- * @return the flags that have been set. A combination of the constants
- * defined in this class.
- *
- * @see #CANON_EQ
- * @see #CASE_INSENSITIVE
- * @see #COMMENTS
- * @see #DOTALL
- * @see #LITERAL
- * @see #MULTILINE
- * @see #UNICODE_CASE
- * @see #UNIX_LINES
- *
- * @since Android 1.0
- */
- public int flags() {
- return flags;
- }
-
- /**
- * Returns a {@link Matcher} for the {@code Pattern} and a given input. The
- * {@code Matcher} can be used to match the {@code Pattern} against the
- * whole input, find occurrences of the {@code Pattern} in the input, or
- * replace parts of the input.
- *
- * @param input
- * the input to process.
- *
- * @return the resulting {@code Matcher}.
- *
- * @since Android 1.0
- */
- public Matcher matcher(CharSequence input) {
- return new Matcher(this, input);
- }
-
- /**
* Tries to match a given regular expression against a given input. This is
* actually nothing but a convenience method that compiles the regular
* expression into a {@code Pattern}, builds a {@link Matcher} for it, and
@@ -332,107 +401,12 @@
*
* @see Pattern#compile(java.lang.String, int)
* @see Matcher#matches()
- *
- * @since Android 1.0
*/
- static public boolean matches(String regex, CharSequence input) {
+ public static boolean matches(String regex, CharSequence input) {
return new Matcher(new Pattern(regex, 0), input).matches();
}
/**
- * Splits a given input around occurrences of a regular expression. This is
- * a convenience method that is equivalent to calling the method
- * {@link #split(java.lang.CharSequence, int)} with a limit of 0.
- *
- * @param input
- * the input sequence.
- *
- * @return the resulting array.
- *
- * @since Android 1.0
- */
- public String[] split(CharSequence input) {
- return split(input, 0);
- }
-
- /**
- * Splits the given input sequence at occurrences of this {@code Pattern}.
- *
- * If this {@code Pattern} does not occur in the input, the result is an
- * array containing the input (converted from a {@code CharSequence} to
- * a {@code String}).
- *
- * Otherwise, the {@code limit} parameter controls the contents of the
- * returned array as described below.
- *
- * @param inputSeq
- * the input sequence.
- * @param limit
- * Determines the maximum number of entries in the resulting
- * array, and the treatment of trailing empty strings.
- * <ul>
- * <li>For n > 0, the resulting array contains at most n
- * entries. If this is fewer than the number of matches, the
- * final entry will contain all remaining input.
- * <li>For n < 0, the length of the resulting array is
- * exactly the number of occurrences of the {@code Pattern}
- * plus one for the text after the final separator.
- * All entries are included.
- * <li>For n == 0, the result is as for n < 0, except
- * trailing empty strings will not be returned. (Note that
- * the case where the input is itself an empty string is
- * special, as described above, and the limit parameter does
- * not apply there.)
- * </ul>
- *
- * @return the resulting array.
- *
- * @since Android 1.0
- */
- public String[] split(CharSequence inputSeq, int limit) {
- if (inputSeq.length() == 0) {
- // Unlike Perl, which considers the result of splitting the empty
- // string to be the empty array, Java returns an array containing
- // the empty string.
- return new String[] { "" };
- }
-
- int maxLength = limit <= 0 ? Integer.MAX_VALUE : limit;
-
- String input = inputSeq.toString();
- ArrayList<String> list = new ArrayList<String>();
-
- Matcher matcher = new Matcher(this, inputSeq);
- int savedPos = 0;
-
- // Add text preceding each occurrence, if enough space.
- while(matcher.find() && list.size() + 1 < maxLength) {
- list.add(input.substring(savedPos, matcher.start()));
- savedPos = matcher.end();
- }
-
- // Add trailing text if enough space.
- if (list.size() < maxLength) {
- if (savedPos < input.length()) {
- list.add(input.substring(savedPos));
- } else {
- list.add("");
- }
- }
-
- // Remove trailing empty matches in the limit == 0 case.
- if (limit == 0) {
- int i = list.size() - 1;
- while (i >= 0 && "".equals(list.get(i))) {
- list.remove(i);
- i--;
- }
- }
-
- return list.toArray(new String[list.size()]);
- }
-
- /**
* Quotes a given string using "\Q" and "\E", so that all other
* meta-characters lose their special meaning. If the string is used for a
* {@code Pattern} afterwards, it can only be matched literally.
@@ -441,27 +415,20 @@
* the string to quote.
*
* @return the quoted string.
- *
- * @since Android 1.0
*/
public static String quote(String s) {
- StringBuffer sb = new StringBuffer().append("\\Q");
+ StringBuilder sb = new StringBuilder().append("\\Q"); //$NON-NLS-1$
int apos = 0;
int k;
- while ((k = s.indexOf("\\E", apos)) >= 0) {
- sb.append(s.substring(apos, k + 2)).append("\\\\E\\Q");
+ while ((k = s.indexOf("\\E", apos)) >= 0) { //$NON-NLS-1$
+ sb.append(s.substring(apos, k + 2)).append("\\\\E\\Q"); //$NON-NLS-1$
apos = k + 2;
}
- return sb.append(s.substring(apos)).append("\\E").toString();
+ return sb.append(s.substring(apos)).append("\\E").toString(); //$NON-NLS-1$
}
@Override
- public String toString() {
- return pattern;
- }
-
- @Override
protected void finalize() throws Throwable {
try {
if (mNativePattern != 0) {
@@ -474,7 +441,7 @@
}
/**
- * Provides serialization support
+ * Serialization support
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
diff --git a/regex/src/main/java/java/util/regex/PatternSyntaxException.java b/regex/src/main/java/java/util/regex/PatternSyntaxException.java
index e4d5abd..d59bdd4 100644
--- a/regex/src/main/java/java/util/regex/PatternSyntaxException.java
+++ b/regex/src/main/java/java/util/regex/PatternSyntaxException.java
@@ -1,17 +1,18 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package java.util.regex;
@@ -25,24 +26,22 @@
*
* @see Pattern#compile(String)
* @see Pattern#compile(java.lang.String,int)
- *
- * @since Android 1.0
*/
public class PatternSyntaxException extends IllegalArgumentException {
private static final long serialVersionUID = -3864639126226059218L;
-
- /**
- * Holds the syntactically incorrect regular expression, or null if the
- * regular expression is not known.
- */
- private String pattern;
/**
* Holds the description of the syntax error, or null if the description is
* not known.
*/
- private String description;
+ private String desc;
+
+ /**
+ * Holds the syntactically incorrect regular expression, or null if the
+ * regular expression is not known.
+ */
+ private String pattern;
/**
* Holds the index around which the error occured, or -1, in case it is
@@ -63,11 +62,10 @@
* @param index
* the character index around which the error occurred, or -1 if
* the index is not known.
- * @since Android 1.0
*/
public PatternSyntaxException(String description, String pattern, int index) {
+ this.desc = description;
this.pattern = pattern;
- this.description = description;
this.index = index;
}
@@ -76,7 +74,6 @@
*
* @return the regular expression.
*
- * @since Android 1.0
*/
public String getPattern() {
return pattern;
@@ -88,16 +85,15 @@
* original regular expression, and the index at which the error occured.
*
* @return the error message.
- *
- * @since Android 1.0
*/
@Override
public String getMessage() {
+ // BEGIN android-changed
StringBuilder builder = new StringBuilder("Syntax error");
- if (description != null) {
+ if (desc != null) {
builder.append(' ');
- builder.append(description);
+ builder.append(desc);
}
if (index >= 0) {
@@ -118,6 +114,7 @@
}
return builder.toString();
+ // END android-changed
}
/**
@@ -125,10 +122,9 @@
* description is not known.
*
* @return the description.
- * @since Android 1.0
*/
public String getDescription() {
- return description;
+ return desc;
}
/**
@@ -137,10 +133,8 @@
*
* @return the index.
*
- * @since Android 1.0
*/
public int getIndex() {
return index;
}
-
}
diff --git a/run-core-tests b/run-core-tests
index 70ab320..723d36f 100755
--- a/run-core-tests
+++ b/run-core-tests
@@ -25,6 +25,11 @@
mkdir $tmp
chmod 777 $tmp
-exec dalvikvm -Duser.language=en -Duser.region=US -Djava.io.tmpdir=$tmp \
+exec dalvikvm \
+ -Duser.name=root \
+ -Duser.language=en \
+ -Duser.region=US \
+ -Djava.io.tmpdir=$tmp \
+ -Djavax.net.ssl.trustStore=/system/etc/security/cacerts.bks \
-classpath /system/framework/core-tests.jar \
-Xmx64M com.google.coretests.Main "$@"
diff --git a/security/src/main/files/cacerts.bks b/security/src/main/files/cacerts.bks
index 36f4919..583c6fa 100644
--- a/security/src/main/files/cacerts.bks
+++ b/security/src/main/files/cacerts.bks
Binary files differ
diff --git a/security/src/main/files/cacerts/97b4211c.0 b/security/src/main/files/cacerts/97b4211c.0
deleted file mode 100644
index 9417aed..0000000
--- a/security/src/main/files/cacerts/97b4211c.0
+++ /dev/null
@@ -1,47 +0,0 @@
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 419 (0x1a3)
- Signature Algorithm: md5WithRSAEncryption
- Issuer: C=US, O=GTE Corporation, CN=GTE CyberTrust Root
- Validity
- Not Before: Feb 23 23:01:00 1996 GMT
- Not After : Feb 23 23:59:00 2006 GMT
- Subject: C=US, O=GTE Corporation, CN=GTE CyberTrust Root
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:b8:e6:4f:ba:db:98:7c:71:7c:af:44:b7:d3:0f:
- 46:d9:64:e5:93:c1:42:8e:c7:ba:49:8d:35:2d:7a:
- e7:8b:bd:e5:05:31:59:c6:b1:2f:0a:0c:fb:9f:a7:
- 3f:a2:09:66:84:56:1e:37:29:1b:87:e9:7e:0c:ca:
- 9a:9f:a5:7f:f5:15:94:a3:d5:a2:46:82:d8:68:4c:
- d1:37:15:06:68:af:bd:f8:b0:b3:f0:29:f5:95:5a:
- 09:16:61:77:0a:22:25:d4:4f:45:aa:c7:bd:e5:96:
- df:f9:d4:a8:8e:42:cc:24:c0:1e:91:27:4a:b5:6d:
- 06:80:63:39:c4:a2:5e:38:03
- Exponent: 65537 (0x10001)
- Signature Algorithm: md5WithRSAEncryption
- 12:b3:75:c6:5f:1d:e1:61:55:80:00:d4:81:4b:7b:31:0f:23:
- 63:e7:3d:f3:03:f9:f4:36:a8:bb:d9:e3:a5:97:4d:ea:2b:29:
- e0:d6:6a:73:81:e6:c0:89:a3:d3:f1:e0:a5:a5:22:37:9a:63:
- c2:48:20:b4:db:72:e3:c8:f6:d9:7c:be:b1:af:53:da:14:b4:
- 21:b8:d6:d5:96:e3:fe:4e:0c:59:62:b6:9a:4a:f9:42:dd:8c:
- 6f:81:a9:71:ff:f4:0a:72:6d:6d:44:0e:9d:f3:74:74:a8:d5:
- 34:49:e9:5e:9e:e9:b4:7a:e1:e5:5a:1f:84:30:9c:d3:9f:a5:
- 25:d8
-SHA1 Fingerprint=90:DE:DE:9E:4C:4E:9F:6F:D8:86:17:57:9D:D3:91:BC:65:A6:89:64
------BEGIN CERTIFICATE-----
-MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
-VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
-b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
-UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
-cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
-RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
-ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
-1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
-dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
-IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
-bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
------END CERTIFICATE-----
diff --git a/security/src/main/java/java/security/AccessControlException.java b/security/src/main/java/java/security/AccessControlException.java
index 1710e77..ae23ab1 100644
--- a/security/src/main/java/java/security/AccessControlException.java
+++ b/security/src/main/java/java/security/AccessControlException.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code AccessControlException} is thrown if the access control infrastructure
* denies protected access due to missing permissions.
- *
- * @since Android 1.0
*/
public class AccessControlException extends SecurityException {
@@ -37,10 +30,9 @@
/**
* Constructs a new instance of {@code AccessControlException} with the
* given message.
- *
+ *
* @param message
* the detail message for this exception.
- * @since Android 1.0
*/
public AccessControlException(String message) {
super(message);
@@ -49,12 +41,11 @@
/**
* Constructs a new instance of {@code AccessControlException} with the
* given message and the requested {@code Permission} which was not granted.
- *
+ *
* @param message
* the detail message for the exception.
* @param perm
* the requested {@code Permission} which was not granted.
- * @since Android 1.0
*/
public AccessControlException(String message, Permission perm) {
super(message);
@@ -64,9 +55,8 @@
/**
* Returns the requested permission that caused this Exception or {@code
* null} if there is no corresponding {@code Permission}.
- *
+ *
* @return the requested permission that caused this Exception, maybe {@code null}.
- * @since Android 1.0
*/
public Permission getPermission() {
return perm;
diff --git a/security/src/main/java/java/security/AlgorithmParameterGenerator.java b/security/src/main/java/java/security/AlgorithmParameterGenerator.java
index 199efa1..6814813 100644
--- a/security/src/main/java/java/security/AlgorithmParameterGenerator.java
+++ b/security/src/main/java/java/security/AlgorithmParameterGenerator.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
import java.security.spec.AlgorithmParameterSpec;
@@ -30,8 +25,6 @@
/**
* {@code AlgorithmParameterGenerator} is an engine class which is capable of
* generating parameters for the algorithm it was initialized with.
- *
- * @since Android 1.0
*/
public class AlgorithmParameterGenerator {
@@ -56,14 +49,13 @@
/**
* Constructs a new instance of {@code AlgorithmParameterGenerator} with the
* given arguments.
- *
+ *
* @param paramGenSpi
* a concrete implementation, this engine instance delegates to.
* @param provider
* the provider.
* @param algorithm
* the name of the algorithm.
- * @since Android 1.0
*/
protected AlgorithmParameterGenerator(
AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider,
@@ -75,9 +67,8 @@
/**
* Returns the name of the algorithm.
- *
+ *
* @return the name of the algorithm.
- * @since Android 1.0
*/
public final String getAlgorithm() {
return algorithm;
@@ -95,7 +86,6 @@
* if the specified algorithm is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static AlgorithmParameterGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -127,7 +117,6 @@
* if the specified provider is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static AlgorithmParameterGenerator getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
@@ -157,7 +146,6 @@
* if the specified algorithm is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static AlgorithmParameterGenerator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
@@ -178,10 +166,9 @@
/**
* Returns the provider associated with this {@code
* AlgorithmParameterGenerator}.
- *
+ *
* @return the provider associated with this {@code
* AlgorithmParameterGenerator}.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -191,10 +178,9 @@
* Initializes this {@code AlgorithmParameterGenerator} with the given size.
* The default parameter set and a default {@code SecureRandom} instance
* will be used.
- *
+ *
* @param size
* the size (in number of bits).
- * @since Android 1.0
*/
public final void init(int size) {
spiImpl.engineInit(size, randm);
@@ -204,12 +190,11 @@
* Initializes this {@code AlgorithmParameterGenerator} with the given size
* and the given {@code SecureRandom}. The default parameter set will be
* used.
- *
+ *
* @param size
* the size (in number of bits).
* @param random
* the source of randomness.
- * @since Android 1.0
*/
public final void init(int size, SecureRandom random) {
spiImpl.engineInit(size, random);
@@ -219,12 +204,11 @@
* Initializes this {@code AlgorithmParameterGenerator} with the given {@code
* AlgorithmParameterSpec}. A default {@code SecureRandom} instance will be
* used.
- *
+ *
* @param genParamSpec
* the parameters to use.
* @throws InvalidAlgorithmParameterException
* if the specified parameters are not supported.
- * @since Android 1.0
*/
public final void init(AlgorithmParameterSpec genParamSpec)
throws InvalidAlgorithmParameterException {
@@ -234,14 +218,13 @@
/**
* Initializes this {@code AlgorithmParameterGenerator} with the given
* {@code AlgorithmParameterSpec} and the given {@code SecureRandom}.
- *
+ *
* @param genParamSpec
* the parameters to use.
* @param random
* the source of randomness.
* @throws InvalidAlgorithmParameterException
* if the specified parameters are not supported.
- * @since Android 1.0
*/
public final void init(AlgorithmParameterSpec genParamSpec,
SecureRandom random) throws InvalidAlgorithmParameterException {
@@ -251,11 +234,10 @@
/**
* Computes and returns {@code AlgorithmParameters} for this generator's
* algorithm.
- *
+ *
* @return {@code AlgorithmParameters} for this generator's algorithm.
- * @since Android 1.0
*/
public final AlgorithmParameters generateParameters() {
return spiImpl.engineGenerateParameters();
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/AlgorithmParameterGeneratorSpi.java b/security/src/main/java/java/security/AlgorithmParameterGeneratorSpi.java
index 9ddff23..44b3def 100644
--- a/security/src/main/java/java/security/AlgorithmParameterGeneratorSpi.java
+++ b/security/src/main/java/java/security/AlgorithmParameterGeneratorSpi.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
import java.security.spec.AlgorithmParameterSpec;
@@ -29,14 +24,11 @@
* (SPI) definition for {@code AlgorithmParameterGenerator}.
*
* @see AlgorithmParameterGenerator
- * @since Android 1.0
*/
public abstract class AlgorithmParameterGeneratorSpi {
/**
* Constructs a new instance of {@code AlgorithmParameterGeneratorSpi} .
- *
- * @since Android 1.0
*/
public AlgorithmParameterGeneratorSpi() {
}
@@ -45,26 +37,24 @@
* Initializes this {@code AlgorithmParameterGeneratorSpi} with the given
* size and the given {@code SecureRandom}. The default parameter set
* will be used.
- *
+ *
* @param size
* the size (in number of bits).
* @param random
* the source of randomness.
- * @since Android 1.0
*/
protected abstract void engineInit(int size, SecureRandom random);
/**
* Initializes this {@code AlgorithmParameterGeneratorSpi} with the given
* {@code AlgorithmParameterSpec} and the given {@code SecureRandom}.
- *
+ *
* @param genParamSpec
* the parameters to use.
* @param random
* the source of randomness.
* @throws InvalidAlgorithmParameterException
* if the specified parameters are not supported.
- * @since Android 1.0
*/
protected abstract void engineInit(AlgorithmParameterSpec genParamSpec,
SecureRandom random) throws InvalidAlgorithmParameterException;
@@ -72,9 +62,8 @@
/**
* Computes and returns {@code AlgorithmParameters} for this generator's
* algorithm.
- *
+ *
* @return {@code AlgorithmParameters} for this generator's algorithm.
- * @since Android 1.0
*/
protected abstract AlgorithmParameters engineGenerateParameters();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/AlgorithmParameters.java b/security/src/main/java/java/security/AlgorithmParameters.java
index aaefe1b..d659200 100644
--- a/security/src/main/java/java/security/AlgorithmParameters.java
+++ b/security/src/main/java/java/security/AlgorithmParameters.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
@@ -33,8 +28,6 @@
/**
* {@code AlgorithmParameters} is an engine class which provides algorithm
* parameters.
- *
- * @since Android 1.0
*/
public class AlgorithmParameters {
/**
@@ -70,20 +63,16 @@
/**
* Constructs a new instance of {@code AlgorithmParameters} with the given
* arguments.
- *
+ *
* @param algPramSpi
* the concrete implementation.
* @param provider
* the security provider.
* @param algorithm
* the name of the algorithm.
- * @since Android 1.0
*/
protected AlgorithmParameters(AlgorithmParametersSpi algPramSpi,
Provider provider, String algorithm) {
- // BEGIN android-note
- // renamed parameter
- // END android-note
this.provider = provider;
this.algorithm = algorithm;
this.spiImpl = algPramSpi;
@@ -92,7 +81,7 @@
/**
* Returns a new instance of {@code AlgorithmParameters} for the specified
* algorithm.
- *
+ *
* @param algorithm
* the name of the algorithm to use.
* @return a new instance of {@code AlgorithmParameters} for the specified
@@ -101,7 +90,6 @@
* if the specified algorithm is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static AlgorithmParameters getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -118,7 +106,7 @@
/**
* Returns a new instance of {@code AlgorithmParameters} from the specified
* provider for the specified algorithm.
- *
+ *
* @param algorithm
* the name of the algorithm to use.
* @param provider
@@ -133,7 +121,6 @@
* if {@code provider} is {@code null} or of length zero.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static AlgorithmParameters getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
@@ -152,7 +139,7 @@
/**
* Returns a new instance of {@code AlgorithmParameters} from the specified
* provider for the specified algorithm.
- *
+ *
* @param algorithm
* the name of the algorithm to use.
* @param provider
@@ -165,7 +152,6 @@
* if {@code algorithm} is {@code null}.
* @throws IllegalArgumentException
* if {@code provider} is {@code null}.
- * @since Android 1.0
*/
public static AlgorithmParameters getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
@@ -184,9 +170,8 @@
/**
* Returns the provider associated with this {@code AlgorithmParameters}.
- *
+ *
* @return the provider associated with this {@code AlgorithmParameters}.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -194,9 +179,8 @@
/**
* Returns the name of the algorithm.
- *
+ *
* @return the name of the algorithm.
- * @since Android 1.0
*/
public final String getAlgorithm() {
return algorithm;
@@ -205,14 +189,13 @@
/**
* Initializes this {@code AlgorithmParameters} with the specified {@code
* AlgorithmParameterSpec}.
- *
+ *
* @param paramSpec
* the parameter specification.
* @throws InvalidParameterSpecException
* if this {@code AlgorithmParameters} has already been
* initialized or the given {@code paramSpec} is not appropriate
* for initializing this {@code AlgorithmParameters}.
- * @since Android 1.0
*/
public final void init(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException {
@@ -228,13 +211,12 @@
* Initializes this {@code AlgorithmParameters} with the specified {@code
* byte[]} using the default decoding format for parameters. The default
* encoding format is ASN.1.
- *
+ *
* @param params
* the encoded parameters.
* @throws IOException
* if this {@code AlgorithmParameters} has already been
* initialized, or the parameter could not be encoded.
- * @since Android 1.0
*/
public final void init(byte[] params) throws IOException {
if (initialized) {
@@ -247,7 +229,7 @@
/**
* Initializes this {@code AlgorithmParameters} with the specified {@code
* byte[]} using the specified decoding format.
- *
+ *
* @param params
* the encoded parameters.
* @param format
@@ -255,7 +237,6 @@
* @throws IOException
* if this {@code AlgorithmParameters} has already been
* initialized, or the parameter could not be encoded.
- * @since Android 1.0
*/
public final void init(byte[] params, String format) throws IOException {
if (initialized) {
@@ -268,7 +249,7 @@
/**
* Returns the {@code AlgorithmParameterSpec} for this {@code
* AlgorithmParameters}.
- *
+ *
* @param paramSpec
* the type of the parameter specification in which this
* parameters should be converted.
@@ -278,7 +259,6 @@
* if this {@code AlgorithmParameters} has already been
* initialized, or if this parameters could not be converted to
* the specified class.
- * @since Android 1.0
*/
public final <T extends AlgorithmParameterSpec> T getParameterSpec(Class<T> paramSpec)
throws InvalidParameterSpecException {
@@ -292,12 +272,11 @@
/**
* Returns this {@code AlgorithmParameters} in their default encoding
* format. The default encoding format is ASN.1.
- *
+ *
* @return the encoded parameters.
* @throws IOException
* if this {@code AlgorithmParameters} has already been
* initialized, or if this parameters could not be encoded.
- * @since Android 1.0
*/
public final byte[] getEncoded() throws IOException {
if (!initialized) {
@@ -309,14 +288,13 @@
/**
* Returns this {@code AlgorithmParameters} in the specified encoding
* format.
- *
+ *
* @param format
* the name of the encoding format.
* @return the encoded parameters.
* @throws IOException
* if this {@code AlgorithmParameters} has already been
* initialized, or if this parameters could not be encoded.
- * @since Android 1.0
*/
public final byte[] getEncoded(String format) throws IOException {
if (!initialized) {
@@ -328,10 +306,10 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code AlgorithmParameters}.
- *
+ *
* @return a printable representation for this {@code AlgorithmParameters}.
- * @since Android 1.0
*/
+ @Override
public final String toString() {
if (!initialized) {
return null;
diff --git a/security/src/main/java/java/security/AlgorithmParametersSpi.java b/security/src/main/java/java/security/AlgorithmParametersSpi.java
index 3bc8891..41b30bc 100644
--- a/security/src/main/java/java/security/AlgorithmParametersSpi.java
+++ b/security/src/main/java/java/security/AlgorithmParametersSpi.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
@@ -37,14 +32,13 @@
/**
* Initializes this {@code AlgorithmParametersSpi} with the specified
* {@code AlgorithmParameterSpec}.
- *
+ *
* @param paramSpec
* the parameter specification.
* @throws InvalidParameterSpecException
* if this {@code AlgorithmParametersSpi} has already been
* initialized or the given {@code paramSpec} is not appropriate
* for initializing this {@code AlgorithmParametersSpi}.
- * @since Android 1.0
*/
protected abstract void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException;
@@ -53,20 +47,19 @@
* Initializes this {@code AlgorithmParametersSpi} with the specified
* {@code byte[]} using the default decoding format for parameters. The
* default encoding format is ASN.1.
- *
+ *
* @param params
* the encoded parameters.
* @throws IOException
* if this {@code AlgorithmParametersSpi} has already been
* initialized, or the parameter could not be encoded.
- * @since Android 1.0
*/
protected abstract void engineInit(byte[] params) throws IOException;
/**
* Initializes this {@code AlgorithmParametersSpi} with the specified
* {@code byte[]} using the specified decoding format.
- *
+ *
* @param params
* the encoded parameters.
* @param format
@@ -74,7 +67,6 @@
* @throws IOException
* if this {@code AlgorithmParametersSpi} has already been
* initialized, or the parameter could not be encoded.
- * @since Android 1.0
*/
protected abstract void engineInit(byte[] params, String format)
throws IOException;
@@ -82,7 +74,7 @@
/**
* Returns the {@code AlgorithmParameterSpec} for this {@code
* AlgorithmParametersSpi}.
- *
+ *
* @param paramSpec
* the type of the parameter specification in which this
* parameters should be converted.
@@ -92,7 +84,6 @@
* if this {@code AlgorithmParametersSpi} has already been
* initialized, or if this parameters could not be converted to
* the specified class.
- * @since Android 1.0
*/
protected abstract <T extends AlgorithmParameterSpec> T engineGetParameterSpec(
Class<T> paramSpec) throws InvalidParameterSpecException;
@@ -100,25 +91,23 @@
/**
* Returns the parameters in their default encoding format. The default
* encoding format is ASN.1.
- *
+ *
* @return the encoded parameters.
* @throws IOException
* if this {@code AlgorithmParametersSpi} has already been
* initialized, or if this parameters could not be encoded.
- * @since Android 1.0
*/
protected abstract byte[] engineGetEncoded() throws IOException;
/**
* Returns the parameters in the specified encoding format.
- *
+ *
* @param format
* the name of the encoding format.
* @return the encoded parameters.
* @throws IOException
* if this {@code AlgorithmParametersSpi} has already been
* initialized, or if this parameters could not be encoded.
- * @since Android 1.0
*/
protected abstract byte[] engineGetEncoded(String format)
throws IOException;
@@ -126,11 +115,10 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code AlgorithmParametersSpi}.
- *
+ *
* @return a printable representation for this {@code
* AlgorithmParametersSpi}.
- * @since Android 1.0
*/
protected abstract String engineToString();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/AllPermission.java b/security/src/main/java/java/security/AllPermission.java
index f4b8aad..c12bb27 100644
--- a/security/src/main/java/java/security/AllPermission.java
+++ b/security/src/main/java/java/security/AllPermission.java
@@ -22,11 +22,12 @@
* {@code AllPermission} represents the permission to perform any operation.
* Since its {@link #implies(Permission)} method always returns {@code true},
* granting this permission is equivalent to disabling security.
- *
- * @since Android 1.0
*/
public final class AllPermission extends Permission {
+ /**
+ * @serial
+ */
private static final long serialVersionUID = -2916474571451318075L;
// Permission name
@@ -40,12 +41,11 @@
* version is provided for class {@code Policy} so that it has a consistent
* call pattern across all permissions. The name and action list are both
* ignored.
- *
+ *
* @param name
* ignored.
* @param actions
* ignored.
- * @since Android 1.0
*/
public AllPermission(String name, String actions) {
super(ALL_PERMISSIONS);
@@ -53,8 +53,6 @@
/**
* Constructs a new instance of {@code AllPermission}.
- *
- * @since Android 1.0
*/
public AllPermission() {
super(ALL_PERMISSIONS);
@@ -65,15 +63,15 @@
* equality and returns {@code true} if the specified object is equal,
* {@code false} otherwise. To be equal, the given object needs to be an
* instance of {@code AllPermission}.
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* AllPermission}.
* @return {@code true} if the specified object is equal to this {@code
* AllPermission}, otherwise {@code false}.
- * @since Android 1.0
* @see #hashCode
*/
+ @Override
public boolean equals(Object obj) {
return (obj instanceof AllPermission);
}
@@ -82,12 +80,12 @@
* Returns the hash code value for this {@code AllPermission}. Returns the
* same hash code for {@code AllPermission}s that are equal to each other as
* required by the general contract of {@link Object#hashCode}.
- *
+ *
* @return the hash code value for this {@code AllPermission}.
* @see Object#equals(Object)
* @see AllPermission#equals(Object)
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
return 1;
}
@@ -96,10 +94,10 @@
* Returns the actions associated with this {@code AllPermission}. Since
* {@code AllPermission} objects allow all actions, this method returns
* always the string "<all actions>".
- *
+ *
* @return the actions associated with this {@code AllPermission}.
- * @since Android 1.0
*/
+ @Override
public String getActions() {
return ALL_ACTIONS;
}
@@ -107,12 +105,12 @@
/**
* Indicates whether the given permission is implied by this permission.
* {@code AllPermission} objects imply all other permissions.
- *
+ *
* @return always {@code true}.
* @param permission
* the permission to check.
- * @since Android 1.0
*/
+ @Override
public boolean implies(Permission permission) {
return true;
}
@@ -120,10 +118,10 @@
/**
* Returns a new {@code PermissionCollection} for holding permissions of
* this class.
- *
+ *
* @return a new {@code PermissionCollection}.
- * @since Android 1.0
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new AllPermissionCollection();
}
diff --git a/security/src/main/java/java/security/AllPermissionCollection.java b/security/src/main/java/java/security/AllPermissionCollection.java
index 000365d..5b28420 100644
--- a/security/src/main/java/java/security/AllPermissionCollection.java
+++ b/security/src/main/java/java/security/AllPermissionCollection.java
@@ -32,13 +32,9 @@
* single added instance.
*
* @see AllPermission
- * @since Android 1.0
*/
final class AllPermissionCollection extends PermissionCollection {
- /**
- * @com.intel.drl.spec_ref
- */
private static final long serialVersionUID = -4023755556366636806L;
private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
@@ -50,6 +46,7 @@
/**
* Adds an {@code AllPermission} to the collection.
*/
+ @Override
public void add(Permission permission) {
if (isReadOnly()) {
throw new SecurityException(Messages.getString("security.15")); //$NON-NLS-1$
@@ -64,6 +61,7 @@
/**
* Returns the enumeration of the collection.
*/
+ @Override
public Enumeration<Permission> elements() {
return new SingletonEnumeration<Permission>(all);
}
@@ -78,6 +76,7 @@
/**
* Constructor taking the single element.
+ * @param single the element
*/
public SingletonEnumeration(E single) {
element = single;
@@ -112,6 +111,7 @@
* @param permission
* the permission to check.
*/
+ @Override
public boolean implies(Permission permission) {
return all != null;
}
@@ -137,4 +137,4 @@
all = new AllPermission();
}
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/AuthProvider.java b/security/src/main/java/java/security/AuthProvider.java
index 5a3be77..15324b3 100644
--- a/security/src/main/java/java/security/AuthProvider.java
+++ b/security/src/main/java/java/security/AuthProvider.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import javax.security.auth.Subject;
@@ -29,11 +24,12 @@
/**
* {@code AuthProvider} is an abstract superclass for Java Security {@code
* Provider} which provide login and logout.
- *
- * @since Android 1.0
*/
public abstract class AuthProvider extends Provider {
+ /**
+ * @serial
+ */
private static final long serialVersionUID = 4197859053084546461L;
/**
@@ -46,7 +42,6 @@
* the version of the provider.
* @param info
* a description of the provider.
- * @since Android 1.0
*/
protected AuthProvider(String name, double version, String info) {
super(name, version, info);
@@ -71,7 +66,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public abstract void login(Subject subject, CallbackHandler handler) throws LoginException;
@@ -82,14 +76,12 @@
* the {@code SecurityPermission} {@code authProvider.NAME} (where NAME is
* the provider name) to be granted, otherwise a {@code SecurityException}
* will be thrown.
- * </p>
- *
+ *
* @throws LoginException
* if the logout fails.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public abstract void logout() throws LoginException;
@@ -101,20 +93,18 @@
* If no handler is set, this {@code AuthProvider} uses the {@code
* CallbackHandler} specified by the {@code
* auth.login.defaultCallbackHandler} security property.
- * </p><p>
+ * <p>
* If a {@code SecurityManager} is installed, code calling this method needs
* the {@code SecurityPermission} {@code authProvider.NAME} (where NAME is
* the provider name) to be granted, otherwise a {@code SecurityException}
* will be thrown.
- * </p>
- *
+ *
* @param handler
* the handler to obtain authentication information from the
* caller.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public abstract void setCallbackHandler(CallbackHandler handler);
}
diff --git a/security/src/main/java/java/security/BasicPermission.java b/security/src/main/java/java/security/BasicPermission.java
index 1d566ec..aa49cba 100644
--- a/security/src/main/java/java/security/BasicPermission.java
+++ b/security/src/main/java/java/security/BasicPermission.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
@@ -38,14 +33,13 @@
* For example:
*
* <pre>
- * com.google.android.* grants all permissions under the com.google.android permission hierarchy
- * * grants all permissions
+ * java.io.* grants all permissions under the java.io permission hierarchy
+ * * grants all permissions
* </pre>
- * </p><p>
+ * <p>
* While this class ignores the action list in the
* {@link #BasicPermission(String, String)} constructor, subclasses may
* implement actions on top of this class.
- * </p>
*/
public abstract class BasicPermission extends Permission implements
Serializable {
@@ -55,12 +49,11 @@
/**
* Constructs a new instance of {@code BasicPermission} with the specified
* name.
- *
+ *
* @param name
* the name of the permission.
* @throws NullPointerException if {@code name} is {@code null}.
* @throws IllegalArgumentException if {@code name.length() == 0}.
- * @since Android 1.0
*/
public BasicPermission(String name) {
super(name);
@@ -70,7 +63,7 @@
/**
* Constructs a new instance of {@code BasicPermission} with the specified
* name. The {@code action} parameter is ignored.
- *
+ *
* @param name
* the name of the permission.
* @param action
@@ -79,7 +72,6 @@
* if {@code name} is {@code null}.
* @throws IllegalArgumentException
* if {@code name.length() == 0}.
- * @since Android 1.0
*/
public BasicPermission(String name, String action) {
super(name);
@@ -105,15 +97,14 @@
* <p>
* The {@link #implies(Permission)} method should be used for making access
* control checks.
- * </p>
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* BasicPermission}.
* @return {@code true} if the specified object is equal to this {@code
* BasicPermission}, otherwise {@code false}.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
@@ -129,12 +120,12 @@
* Returns the hash code value for this {@code BasicPermission}. Returns the
* same hash code for {@code BasicPermission}s that are equal to each other
* as required by the general contract of {@link Object#hashCode}.
- *
+ *
* @return the hash code value for this {@code BasicPermission}.
* @see Object#equals(Object)
* @see BasicPermission#equals(Object)
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
return getName().hashCode();
}
@@ -142,23 +133,23 @@
/**
* Returns the actions associated with this permission. Since {@code
* BasicPermission} instances have no actions, an empty string is returned.
- *
+ *
* @return an empty string.
- * @since Android 1.0
*/
+ @Override
public String getActions() {
return ""; //$NON-NLS-1$
}
/**
* Indicates whether the specified permission is implied by this permission.
- *
+ *
* @param permission
* the permission to check against this permission.
* @return {@code true} if the specified permission is implied by this
* permission, {@code false} otherwise.
- * @since Android 1.0
*/
+ @Override
public boolean implies(Permission permission) {
if (permission != null && permission.getClass() == this.getClass()) {
return nameImplies(getName(), permission.getName());
@@ -204,12 +195,11 @@
* stored in it when checking if the collection implies a permission.
* Instead, it assumes that if the type of the permission is correct, and
* the name of the permission is correct, there is a match.
- * </p>
- *
+ *
* @return an empty {@link PermissionCollection} for holding permissions.
* @see BasicPermissionCollection
- * @since Android 1.0
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new BasicPermissionCollection();
}
@@ -222,4 +212,4 @@
in.defaultReadObject();
checkName(this.getName());
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/BasicPermissionCollection.java b/security/src/main/java/java/security/BasicPermissionCollection.java
index eb80503..820ae7f 100644
--- a/security/src/main/java/java/security/BasicPermissionCollection.java
+++ b/security/src/main/java/java/security/BasicPermissionCollection.java
@@ -37,7 +37,6 @@
*
* @see BasicPermission
* @see PermissionCollection
- * @since Android 1.0
*/
final class BasicPermissionCollection extends PermissionCollection {
@@ -63,6 +62,7 @@
*
* @see java.security.PermissionCollection#add(java.security.Permission)
*/
+ @Override
public void add(Permission permission) {
if (isReadOnly()) {
throw new SecurityException(Messages.getString("security.15")); //$NON-NLS-1$
@@ -82,8 +82,6 @@
permission));
} else {
// this is the first element provided that another thread did not add
- // BEGIN android-changed
- // copied from a newer version of harmony
synchronized (this) {
if (permClass != null && inClass != permClass) {
throw new IllegalArgumentException(Messages.getString("security.16", //$NON-NLS-1$
@@ -91,7 +89,6 @@
}
permClass = inClass;
}
- // END android-changed
}
String name = permission.getName();
@@ -102,6 +99,7 @@
/**
* Returns enumeration of contained elements.
*/
+ @Override
public Enumeration<Permission> elements() {
return Collections.enumeration(items.values());
}
@@ -115,6 +113,7 @@
* the permission to check.
* @see Permission
*/
+ @Override
public boolean implies(Permission permission) {
if (permission == null || permission.getClass() != permClass) {
return false;
@@ -162,16 +161,10 @@
* <dd>The class to which all {@code BasicPermission}s in this
* BasicPermissionCollection belongs.
* <dt>Hashtable<K,V> permissions
- * <dd>The
- *
- * <pre>
- * BasicPermission
- * </pre>
- *
- * s in this {@code BasicPermissionCollection}. All {@code BasicPermission}s
- * in the collection must belong to the same class. The Hashtable is indexed
- * by the {@code BasicPermission} name; the value of the Hashtable entry is
- * the permission.
+ * <dd>The {@code BasicPermission}s in this collection. All {@code
+ * BasicPermission}s in the collection must belong to the same class. The
+ * Hashtable is indexed by the {@code BasicPermission} name; the value of
+ * the Hashtable entry is the permission.
* </dl>
*/
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
@@ -191,8 +184,6 @@
ObjectInputStream.GetField fields = in.readFields();
items = new HashMap<String, Permission>();
- // BEGIN android-changed
- // copied from a newer version of harmony
synchronized (this) {
permClass = (Class<? extends Permission>)fields.get("permClass", null); //$NON-NLS-1$
items.putAll((Hashtable<String, Permission>) fields.get(
@@ -207,6 +198,5 @@
throw new InvalidObjectException(Messages.getString("security.25")); //$NON-NLS-1$
}
}
- // END android-changed
}
}
diff --git a/security/src/main/java/java/security/Certificate.java b/security/src/main/java/java/security/Certificate.java
index bf9a1ae..b30352d 100644
--- a/security/src/main/java/java/security/Certificate.java
+++ b/security/src/main/java/java/security/Certificate.java
@@ -15,15 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
-// BEGIN android-note
-// Added Deprecated annotation.
-// END android-note
-
package java.security;
import java.io.IOException;
@@ -36,9 +27,8 @@
* validity of itself. It's in the responsibility of the application to verify
* the validity of its certificates.
*
- * @deprecated Replaced by behavior in {@link javax.security.cert}
+ * @deprecated Replaced by behavior in {@link java.security.cert}
* @see java.security.cert.Certificate
- * @since Android 1.0
*/
@Deprecated
public interface Certificate {
@@ -47,7 +37,7 @@
* Decodes a certificate from the given {@code InputStream}. The format of
* the data to encode must be that identified by {@link #getFormat()} and
* encoded by {@link #encode(OutputStream)}.
- *
+ *
* @param stream
* the {@code InputStream} to read from.
* @throws KeyException
@@ -56,7 +46,6 @@
* if an exception is thrown by accessing the provided stream.
* @see #encode(OutputStream)
* @see #getFormat()
- * @since Android 1.0
*/
public void decode(InputStream stream) throws KeyException, IOException;
@@ -64,7 +53,7 @@
* Encodes this certificate to an output stream. The
* {@link #decode(InputStream)} method must be able to decode the format
* written by this method.
- *
+ *
* @param stream
* the {@code OutputStream} to encode this certificate to.
* @throws KeyException
@@ -72,15 +61,13 @@
* @throws IOException
* if an exception is thrown by accessing the provided stream.
* @see #decode(InputStream)
- * @since Android 1.0
*/
public void encode(OutputStream stream) throws KeyException, IOException;
/**
* Returns a string identifying the format of this certificate.
- *
+ *
* @return a string identifying the format of this certificate.
- * @since Android 1.0
*/
public String getFormat();
@@ -88,42 +75,38 @@
* Returns the guarantor of this certificate. That guarantor guarantees,
* that the public key of this certificate is from the principal returned by
* {@link #getPrincipal()}.
- *
+ *
* @return the guarantor of this certificate.
* @see #getPrincipal()
- * @since Android 1.0
*/
public Principal getGuarantor();
/**
* Returns the principal of this certificate. The principal is guaranteed by
* the guarantor returned by {@link #getGuarantor()}.
- *
+ *
* @return the principal of this certificate.
* @see #getGuarantor()
- * @since Android 1.0
*/
public Principal getPrincipal();
/**
* Returns the public key of this certificate. The public key is guaranteed
* by the guarantor to belong to the principal.
- *
+ *
* @return the public key of this certificate.
* @see #getGuarantor()
* @see Certificate#getPrincipal()
- * @since Android 1.0
*/
public PublicKey getPublicKey();
/**
* Returns a string containing a concise, human-readable description of the
* this {@code Certificate}.
- *
+ *
* @param detailed
* whether or not this method should return detailed information.
* @return a string representation of this certificate.
- * @since Android 1.0
*/
public String toString(boolean detailed);
}
diff --git a/security/src/main/java/java/security/CodeSigner.java b/security/src/main/java/java/security/CodeSigner.java
index 0719e8f..24d2b55 100644
--- a/security/src/main/java/java/security/CodeSigner.java
+++ b/security/src/main/java/java/security/CodeSigner.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
import java.io.Serializable;
@@ -29,8 +24,6 @@
/**
* {@code CodeSigner} represents a signer of code. Instances are immutable.
- *
- * @since Android 1.0
*/
public final class CodeSigner implements Serializable {
@@ -45,7 +38,7 @@
/**
* Constructs a new instance of {@code CodeSigner}.
- *
+ *
* @param signerCertPath
* the certificate path associated with this code signer.
* @param timestamp
@@ -53,7 +46,6 @@
* null}.
* @throws NullPointerException
* if {@code signerCertPath} is {@code null}.
- * @since Android 1.0
*/
public CodeSigner(CertPath signerCertPath, Timestamp timestamp) {
if (signerCertPath == null) {
@@ -68,14 +60,14 @@
* Returns {@code true} if the specified object is also an instance of
* {@code CodeSigner}, the two {@code CodeSigner} encapsulate the same
* certificate path and the same time stamp, if present in both.
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* CodeSigner}.
* @return {@code true} if the specified object is equal to this {@code
* CodeSigner}, otherwise {@code false}.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
@@ -93,9 +85,8 @@
/**
* Returns the certificate path associated with this {@code CodeSigner}.
- *
+ *
* @return the certificate path associated with this {@code CodeSigner}.
- * @since Android 1.0
*/
public CertPath getSignerCertPath() {
return signerCertPath;
@@ -103,10 +94,9 @@
/**
* Returns the time stamp associated with this {@code CodeSigner}.
- *
+ *
* @return the time stamp associated with this {@code CodeSigner}, maybe
* {@code null}.
- * @since Android 1.0
*/
public Timestamp getTimestamp() {
return timestamp;
@@ -116,12 +106,12 @@
* Returns the hash code value for this {@code CodeSigner}. Returns the same
* hash code for {@code CodeSigner}s that are equal to each other as
* required by the general contract of {@link Object#hashCode}.
- *
+ *
* @return the hash code value for this {@code CodeSigner}.
* @see Object#equals(Object)
* @see CodeSigner#equals(Object)
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
if (hash == 0) {
hash = signerCertPath.hashCode()
@@ -134,14 +124,13 @@
* Returns a string containing a concise, human-readable description of the
* this {@code CodeSigner} including its first certificate and its time
* stamp, if present.
- *
+ *
* @return a printable representation for this {@code CodeSigner}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
// There is no any special reason for '256' here, it's taken abruptly
- // FIXME: 1.5 StringBuffer => StringBuilder
- StringBuffer buf = new StringBuffer(256);
+ StringBuilder buf = new StringBuilder(256);
// The javadoc says nothing, and the others implementations behavior seems as
// dumping only the first certificate. Well, let's do the same.
buf.append("CodeSigner [").append(signerCertPath.getCertificates().get(0)); //$NON-NLS-1$
@@ -151,4 +140,4 @@
buf.append("]"); //$NON-NLS-1$
return buf.toString();
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/CodeSource.java b/security/src/main/java/java/security/CodeSource.java
index f4da89c..96a4b8c5 100644
--- a/security/src/main/java/java/security/CodeSource.java
+++ b/security/src/main/java/java/security/CodeSource.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
import java.io.ByteArrayInputStream;
@@ -48,10 +43,9 @@
* {@code CodeSource} encapsulates the location from where code is loaded and
* the certificates that were used to verify that code. This information is used
* by {@code SecureClassLoader} to define protection domains for loaded classes.
- *
+ *
* @see SecureClassLoader
* @see ProtectionDomain
- * @since Android 1.0
*/
public class CodeSource implements Serializable {
@@ -76,14 +70,13 @@
/**
* Constructs a new instance of {@code CodeSource} with the specified
* {@code URL} and the {@code Certificate}s.
- *
+ *
* @param location
* the {@code URL} representing the location from where code is
* loaded, maybe {@code null}.
* @param certs
* the {@code Certificate} used to verify the code, loaded from
* the specified {@code location}, maybe {@code null}.
- * @since Android 1.0
*/
public CodeSource(URL location, Certificate[] certs) {
this.location = location;
@@ -96,14 +89,13 @@
/**
* Constructs a new instance of {@code CodeSource} with the specified
* {@code URL} and the {@code CodeSigner}s.
- *
+ *
* @param location
* the {@code URL} representing the location from where code is
* loaded, maybe {@code null}.
* @param signers
* the {@code CodeSigner}s of the code, loaded from the specified
* {@code location}. Maybe {@code null}.
- * @since Android 1.0
*/
public CodeSource(URL location, CodeSigner[] signers) {
this.location = location;
@@ -119,14 +111,14 @@
* {@code CodeSource}, points to the same {@code URL} location and the two
* code sources encapsulate the same {@code Certificate}s. The order of the
* {@code Certificate}s is ignored by this method.
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* CodeSource}.
* @return {@code true} if the specified object is equal to this {@code
* CodeSource}, otherwise {@code false}.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
@@ -169,11 +161,9 @@
* <p>
* External modifications of the returned {@code Certificate[]} has no
* impact on this {@code CodeSource}.
- * </p>
- *
+ *
* @return the certificates of this {@code CodeSource} or {@code null} if
* there is none.
- * @since Android 1.0
*/
public final Certificate[] getCertificates() {
getCertificatesNoClone();
@@ -213,10 +203,9 @@
* {@link #CodeSource(URL, Certificate[])} constructor was used to create
* this instance, the signers are obtained from the supplied certificates.
* Only X.509 certificates are analyzed.
- *
+ *
* @return the signers of this {@code CodeSource}, or {@code null} if there
* is none.
- * @since Android 1.0
*/
public final CodeSigner[] getCodeSigners() {
if (signers != null) {
@@ -308,9 +297,8 @@
/**
* Returns the location of this {@code CodeSource}.
- *
+ *
* @return the location of this {@code CodeSource}, maybe {@code null}.
- * @since Android 1.0
*/
public final URL getLocation() {
return location;
@@ -321,12 +309,12 @@
* Returns the same hash code for {@code CodeSource}s that are
* equal to each other as required by the general contract of
* {@link Object#hashCode}.
- *
+ *
* @return the hash code value for this {@code CodeSource}.
* @see Object#equals(Object)
* @see CodeSource#equals(Object)
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
//
// hashCode() is undocumented there. Should we also use certs[i] to
@@ -385,21 +373,20 @@
* location file with the '/' appended to it.
* </ul>
* Examples for locations that imply the location
- * "http://code.google.com/android/security.apk":
- *
+ * "http://harmony.apache.org/milestones/M9/apache-harmony.jar":
+ *
* <pre>
* http:
- * http://*/android/*
- * http://*.google.com/android/*
- * http://code.google.com/android/-
- * http://code.google.com/android/security.apk
+ * http://*/milestones/M9/*
+ * http://*.apache.org/milestones/M9/*
+ * http://harmony.apache.org/milestones/-
+ * http://harmony.apache.org/milestones/M9/apache-harmony.jar
* </pre>
- *
+ *
* @param cs
* the code source to check.
* @return {@code true} if the argument code source is implied by this
* {@code CodeSource}, otherwise {@code false}.
- * @since Android 1.0
*/
public boolean implies(CodeSource cs) {
//
@@ -551,10 +538,10 @@
* Returns a string containing a concise, human-readable description of the
* this {@code CodeSource} including its location, its certificates and its
* signers.
- *
+ *
* @return a printable representation for this {@code CodeSource}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("CodeSource, url="); //$NON-NLS-1$
diff --git a/security/src/main/java/java/security/DigestException.java b/security/src/main/java/java/security/DigestException.java
index d579885..0d0a1ee 100644
--- a/security/src/main/java/java/security/DigestException.java
+++ b/security/src/main/java/java/security/DigestException.java
@@ -15,17 +15,10 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
*{@code DigestException} is a general message digest exception.
- *
- *@since Android 1.0
*/
public class DigestException extends GeneralSecurityException {
@@ -34,10 +27,9 @@
/**
* Constructs a new instance of {@code DigestException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public DigestException(String msg) {
super(msg);
@@ -45,8 +37,6 @@
/**
* Constructs a new instance of {@code DigestException}.
- *
- * @since Android 1.0
*/
public DigestException() {
}
@@ -54,12 +44,11 @@
/**
* Constructs a new instance of {@code DigestException} with the
* given message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public DigestException(String message, Throwable cause) {
super(message, cause);
@@ -68,10 +57,9 @@
/**
* Constructs a new instance of {@code DigestException} with the
* cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public DigestException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/DigestInputStream.java b/security/src/main/java/java/security/DigestInputStream.java
index 0db7613..26433fa 100644
--- a/security/src/main/java/java/security/DigestInputStream.java
+++ b/security/src/main/java/java/security/DigestInputStream.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vladimir N. Molotkov
-* @version $Revision$
-*/
-
package java.security;
import java.io.FilterInputStream;
@@ -29,15 +24,11 @@
/**
* {@code DigestInputStream} is a {@code FilterInputStream} which maintains an
* associated message digest.
- *
- * @since Android 1.0
*/
public class DigestInputStream extends FilterInputStream {
/**
* The message digest for this stream.
- *
- * @since Android 1.0
*/
protected MessageDigest digest;
@@ -47,12 +38,11 @@
/**
* Constructs a new instance of this {@code DigestInputStream}, using the
* given {@code stream} and the {@code digest}.
- *
+ *
* @param stream
* the input stream.
* @param digest
* the message digest.
- * @since Android 1.0
*/
public DigestInputStream(InputStream stream, MessageDigest digest) {
super(stream);
@@ -61,9 +51,8 @@
/**
* Returns the message digest for this stream.
- *
+ *
* @return the message digest for this stream.
- * @since Android 1.0
*/
public MessageDigest getMessageDigest() {
return digest;
@@ -71,10 +60,9 @@
/**
* Sets the message digest which this stream will use.
- *
+ *
* @param digest
* the message digest which this stream will use.
- * @since Android 1.0
*/
public void setMessageDigest(MessageDigest digest) {
this.digest = digest;
@@ -85,13 +73,12 @@
* for the byte if this function is {@link #on(boolean)}.
* <p>
* This operation is blocking.
- * </p>
- *
+ *
* @return the byte which was read or -1 at end of stream.
* @throws IOException
* if reading the source stream causes an {@code IOException}.
- * @since Android 1.0
*/
+ @Override
public int read() throws IOException {
// read the next byte
int byteRead = in.read();
@@ -111,8 +98,7 @@
* {@link #on(boolean)}.
* <p>
* This operation is blocking.
- * </p>
- *
+ *
* @param b
* the byte array in which to store the bytes
* @param off
@@ -124,8 +110,8 @@
* filtered stream has been reached while reading
* @throws IOException
* if reading the source stream causes an {@code IOException}
- * @since Android 1.0
*/
+ @Override
public int read(byte[] b, int off, int len) throws IOException {
// read next up to len bytes
int bytesRead = in.read(b, off, len);
@@ -141,11 +127,11 @@
/**
* Enables or disables the digest function (default is on).
- *
+ *
* @param on
* {@code true} if the digest should be computed, {@code false}
* otherwise.
- * @since Android 1.0
+ * @see MessageDigest
*/
public void on(boolean on) {
isOn = on;
@@ -154,10 +140,10 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code DigestInputStream} including the digest.
- *
+ *
* @return a printable representation for this {@code DigestInputStream}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
return super.toString() + ", " + digest.toString() + //$NON-NLS-1$
(isOn ? ", is on" : ", is off"); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/security/src/main/java/java/security/DigestOutputStream.java b/security/src/main/java/java/security/DigestOutputStream.java
index 858f8dd..f4cd659 100644
--- a/security/src/main/java/java/security/DigestOutputStream.java
+++ b/security/src/main/java/java/security/DigestOutputStream.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vladimir N. Molotkov
-* @version $Revision$
-*/
-
package java.security;
import java.io.FilterOutputStream;
@@ -34,8 +29,6 @@
/**
* The message digest for this stream.
- *
- * @since Android 1.0
*/
protected MessageDigest digest;
@@ -45,12 +38,11 @@
/**
* Constructs a new instance of this {@code DigestOutputStream}, using the
* given {@code stream} and the {@code digest}.
- *
+ *
* @param stream
* the output stream.
* @param digest
* the message digest.
- * @since Android 1.0
*/
public DigestOutputStream(OutputStream stream, MessageDigest digest) {
super(stream);
@@ -59,9 +51,8 @@
/**
* Returns the message digest for this stream.
- *
+ *
* @return the message digest for this stream.
- * @since Android 1.0
*/
public MessageDigest getMessageDigest() {
return digest;
@@ -69,10 +60,9 @@
/**
* Sets the message digest which this stream will use.
- *
+ *
* @param digest
* the message digest which this stream will use.
- * @since Android 1.0
*/
public void setMessageDigest(MessageDigest digest) {
this.digest = digest;
@@ -81,13 +71,13 @@
/**
* Writes the specified {@code int} to the stream. Updates the digest if
* this function is {@link #on(boolean)}.
- *
+ *
* @param b
* the byte to be written.
* @throws IOException
* if writing to the stream causes a {@code IOException}
- * @since Android 1.0
*/
+ @Override
public void write(int b) throws IOException {
// update digest only if digest functionality is on
if (isOn) {
@@ -100,7 +90,7 @@
/**
* Writes {@code len} bytes into the stream, starting from the specified
* offset. Updates the digest if this function is {@link #on(boolean)}.
- *
+ *
* @param b
* the buffer to write to.
* @param off
@@ -109,8 +99,8 @@
* the number of bytes in {@code b} to write.
* @throws IOException
* if writing to the stream causes an {@code IOException}.
- * @since Android 1.0
*/
+ @Override
public void write(byte[] b, int off, int len) throws IOException {
// update digest only if digest functionality is on
if (isOn) {
@@ -122,11 +112,11 @@
/**
* Enables or disables the digest function (default is on).
- *
+ *
* @param on
* {@code true} if the digest should be computed, {@code false}
* otherwise.
- * @since Android 1.0
+ * @see MessageDigest
*/
public void on(boolean on) {
isOn = on;
@@ -135,10 +125,10 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code DigestOutputStream} including the digest.
- *
+ *
* @return a printable representation for this {@code DigestOutputStream}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
return super.toString() + ", " + digest.toString() + //$NON-NLS-1$
(isOn ? ", is on" : ", is off"); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/security/src/main/java/java/security/DomainCombiner.java b/security/src/main/java/java/security/DomainCombiner.java
index 501c419..36433b3 100644
--- a/security/src/main/java/java/security/DomainCombiner.java
+++ b/security/src/main/java/java/security/DomainCombiner.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
/**
@@ -29,7 +24,6 @@
* @see AccessControlContext
* @see AccessControlContext#AccessControlContext(AccessControlContext,
* DomainCombiner)
- * @since Android 1.0
*/
public interface DomainCombiner {
@@ -37,7 +31,7 @@
* Returns a combination of the two provided {@code ProtectionDomain}
* arrays. Implementers can simply merge the two arrays into one, remove
* duplicates and perform other optimizations.
- *
+ *
* @param current
* the protection domains of the current execution thread (since
* the most recent call to {@link AccessController#doPrivileged}
@@ -47,7 +41,6 @@
* null}.
* @return a single {@code ProtectionDomain} array computed from the two
* provided arrays.
- * @since Android 1.0
*/
ProtectionDomain[] combine(ProtectionDomain[] current,
ProtectionDomain[] assigned);
diff --git a/security/src/main/java/java/security/GeneralSecurityException.java b/security/src/main/java/java/security/GeneralSecurityException.java
index 2a1cacb..78fca29 100644
--- a/security/src/main/java/java/security/GeneralSecurityException.java
+++ b/security/src/main/java/java/security/GeneralSecurityException.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code GeneralSecurityException} is a general security exception and the
* superclass for all security specific exceptions.
- *
- * @since Android 1.0
*/
public class GeneralSecurityException extends Exception {
@@ -35,10 +28,9 @@
/**
* Constructs a new instance of {@code GeneralSecurityException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public GeneralSecurityException(String msg) {
super(msg);
@@ -46,8 +38,6 @@
/**
* Constructs a new instance of {@code GeneralSecurityException}.
- *
- * @since Android 1.0
*/
public GeneralSecurityException() {
}
@@ -55,12 +45,11 @@
/**
* Constructs a new instance of {@code GeneralSecurityException} with the
* given message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public GeneralSecurityException(String message, Throwable cause) {
super(message, cause);
@@ -69,10 +58,9 @@
/**
* Constructs a new instance of {@code GeneralSecurityException} with the
* cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public GeneralSecurityException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/Guard.java b/security/src/main/java/java/security/Guard.java
index 1e4d270..b652054 100644
--- a/security/src/main/java/java/security/Guard.java
+++ b/security/src/main/java/java/security/Guard.java
@@ -15,17 +15,10 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code Guard} implementors protect access to other objects.
- *
- * @since Android 1.0
*/
public interface Guard {
@@ -33,12 +26,11 @@
* Checks whether access to the specified {@code Object} should be granted.
* This method returns silently if access is granted, otherwise a {@code
* SecurityException} is thrown.
- *
+ *
* @param object
* the object to be protected by this {@code Guard}.
* @throws SecurityException
* if access is not granted.
- * @since Android 1.0
*/
public void checkGuard(Object object) throws SecurityException;
}
diff --git a/security/src/main/java/java/security/GuardedObject.java b/security/src/main/java/java/security/GuardedObject.java
index a64d634..34a5113 100644
--- a/security/src/main/java/java/security/GuardedObject.java
+++ b/security/src/main/java/java/security/GuardedObject.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
@@ -28,8 +23,6 @@
/**
* {@code GuardedObject} controls access to an object, by checking all requests
* for the object with a {@code Guard}.
- *
- * @since Android 1.0
*/
public class GuardedObject implements Serializable {
@@ -42,13 +35,12 @@
/**
* Constructs a new instance of {@code GuardedObject} which protects access
* to the specified {@code Object} using the specified {@code Guard}.
- *
+ *
* @param object
* the {@code Object} to protect.
* @param guard
* the {@code Guard} which protects the specified {@code Object},
* maybe {@code null}.
- * @since Android 1.0
*/
public GuardedObject(Object object, Guard guard) {
this.object = object;
@@ -59,11 +51,10 @@
* Returns the guarded {@code Object} if the associated {@code Guard}
* permits access. If access is not granted, then a {@code
* SecurityException} is thrown.
- *
+ *
* @return the guarded object.
* @exception SecurityException
* if access is not granted to the guarded object.
- * @since Android 1.0
*/
public Object getObject() throws SecurityException {
if (guard != null) {
diff --git a/security/src/main/java/java/security/Identity.java b/security/src/main/java/java/security/Identity.java
index 7111029..d55cd3a 100644
--- a/security/src/main/java/java/security/Identity.java
+++ b/security/src/main/java/java/security/Identity.java
@@ -15,15 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
-// BEGIN android-note
-// Added Deprecated annotation.
-// END android-note
-
package java.security;
import java.io.Serializable;
@@ -34,11 +25,10 @@
/**
* {@code Identity} represents an identity like a person or a company.
- *
+ *
* @deprecated The functionality of this class has been replace by
* {@link Principal}, {@link KeyStore} and the {@code
* java.security.cert} package.
- * @since Android 1.0
*/
@Deprecated
public abstract class Identity implements Principal, Serializable {
@@ -56,18 +46,15 @@
/**
* Constructs a new instance of {@code Identity}.
- *
- * @since Android 1.0
*/
protected Identity() {
}
/**
* Creates a new instance of {@code Identity} with the specified name.
- *
+ *
* @param name
* the name of this {@code Identity}.
- * @since Android 1.0
*/
public Identity(String name) {
this.name = name;
@@ -76,7 +63,7 @@
/**
* Creates a new instance of {@code Identity} with the specified name and
* the scope of this {@code Identity}.
- *
+ *
* @param name
* the name of this {@code Identity}.
* @param scope
@@ -84,7 +71,6 @@
* @throws KeyManagementException
* if an {@code Identity} with the same name is already present
* in the specified scope.
- * @since Android 1.0
*/
public Identity(String name, IdentityScope scope)
throws KeyManagementException {
@@ -101,8 +87,7 @@
* If a {@code SecurityManager} is installed, code calling this method needs
* the {@code SecurityPermission} {@code addIdentityCertificate} to be
* granted, otherwise a {@code SecurityException} will be thrown.
- * </p>
- *
+ *
* @param certificate
* the {@code Certificate} to be added to this {@code Identity}.
* @throws KeyManagementException
@@ -110,7 +95,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public void addCertificate(Certificate certificate)
throws KeyManagementException {
@@ -163,7 +147,7 @@
* the {@code SecurityPermission} {@code "removeIdentityCertificate"} to be
* granted, otherwise a {@code SecurityException} will be thrown.
* <p>
- *
+ *
* @param certificate
* the {@code Certificate} to be removed.
* @throws KeyManagementException
@@ -171,7 +155,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public void removeCertificate(Certificate certificate)
throws KeyManagementException {
@@ -196,9 +179,8 @@
* Returns the certificates for this {@code Identity}. External
* modifications of the returned array has no impact on this {@code
* Identity}.
- *
+ *
* @return the {@code Certificates} for this {@code Identity}
- * @since Android 1.0
*/
public Certificate[] certificates() {
if (certificates == null) {
@@ -219,13 +201,11 @@
* <p>
* To be equal, two {@code Identity} objects need to have the same name and
* the same public keys.
- * </p>
- *
+ *
* @param identity
* the identity to check for equality.
* @return {@code true} if the {@code Identity} objects are equal, {@code
* false} otherwise.
- * @since Android 1.0
*/
protected boolean identityEquals(Identity identity) {
if (!name.equals(identity.name)) {
@@ -245,12 +225,11 @@
/**
* Returns a string containing a concise, human-readable description of the
* this {@code Identity}.
- *
+ *
* @param detailed
* whether or not this method should return detailed information.
* @return a printable representation for this {@code Permission}.
- * @since Android 1.0
- */
+ */
public String toString(boolean detailed) {
String s = toString();
if (detailed) {
@@ -264,9 +243,8 @@
/**
* Returns the {@code IdentityScope} of this {@code Identity}.
- *
+ *
* @return the {@code IdentityScope} of this {@code Identity}.
- * @since Android 1.0
*/
public final IdentityScope getScope() {
return scope;
@@ -281,8 +259,7 @@
* If a {@code SecurityManager} is installed, code calling this method needs
* the {@code SecurityPermission} {@code setIdentityPublicKey} to be
* granted, otherwise a {@code SecurityException} will be thrown.
- * </p>
- *
+ *
* @param key
* the {@code PublicKey} to be set.
* @throws KeyManagementException
@@ -291,7 +268,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public void setPublicKey(PublicKey key) throws KeyManagementException {
SecurityManager sm = System.getSecurityManager();
@@ -315,9 +291,8 @@
/**
* Returns the {@code PublicKey} associated with this {@code Identity}.
- *
+ *
* @return the {@code PublicKey} associated with this {@code Identity}.
- * @since Android 1.0
*/
public PublicKey getPublicKey() {
return publicKey;
@@ -332,13 +307,12 @@
* If a {@code SecurityManager} is installed, code calling this method needs
* the {@code SecurityPermission} {@code setIdentityInfo} to be granted,
* otherwise a {@code SecurityException} will be thrown.
- *
+ *
* @param info
* the information to be set.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public void setInfo(String info) {
SecurityManager sm = System.getSecurityManager();
@@ -353,9 +327,8 @@
/**
* Returns the information string of this {@code Identity}.
- *
+ *
* @return the information string of this {@code Identity}.
- * @since Android 1.0
*/
public String getInfo() {
return info;
@@ -369,14 +342,14 @@
* returns {@code true} if the specified object is equal, {@code false}
* otherwise. {@code Identity} objects are considered equal, if they have
* the same name and are in the same scope.
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* Identity}.
* @return {@code true} if the specified object is equal to this {@code
* Identity}, otherwise {@code false}.
- * @since Android 1.0
*/
+ @Override
public final boolean equals(Object obj) {
if (this == obj) {
return true;
@@ -397,9 +370,8 @@
/**
* Returns the name of this {@code Identity}.
- *
+ *
* @return the name of this {@code Identity}.
- * @since Android 1.0
*/
public final String getName() {
return name;
@@ -412,12 +384,12 @@
* Returns the hash code value for this {@code Identity}. Returns the same
* hash code for {@code Identity}s that are equal to each other as required
* by the general contract of {@link Object#hashCode}.
- *
+ *
* @return the hash code value for this {@code Identity}.
* @see Object#equals(Object)
* @see Identity#equals(Object)
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
int hash = 0;
if (name != null) {
@@ -439,22 +411,22 @@
* If a {@code SecurityManager} is installed, code calling this method
* needs the {@code SecurityPermission} {@code printIdentity} to be granted,
* otherwise a {@code SecurityException} will be thrown.
- * </p>
- *
+ *
* @return a printable representation for this {@code Identity}.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
+ @Override
+ @SuppressWarnings("nls")
public String toString() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkSecurityAccess("printIdentity"); //$NON-NLS-1$
+ sm.checkSecurityAccess("printIdentity");
}
- String s = (this.name == null? "" : this.name);
+ String s = (this.name == null ? "" : this.name);
if (scope != null) {
- s += " [" + scope.getName() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ s += " [" + scope.getName() + "]";
}
return s;
}
diff --git a/security/src/main/java/java/security/IdentityScope.java b/security/src/main/java/java/security/IdentityScope.java
index 93729dc..60ab3e8 100644
--- a/security/src/main/java/java/security/IdentityScope.java
+++ b/security/src/main/java/java/security/IdentityScope.java
@@ -15,29 +15,17 @@
* limitations under the License.
*/
-/**
-* @author Aleksei Y. Semenov
-* @version $Revision$
-*/
-
-// BEGIN android-note
-// Added Deprecated annotation.
-// END android-note
-
package java.security;
import java.util.Enumeration;
-import org.apache.harmony.security.SystemScope;
-
/**
* {@code IdentityScope} represents a scope for {@link Identity} objects.
- *
+ *
* @deprecated The functionality of this class has been replace by
* {@link Principal}, {@link KeyStore} and the {@code
* java.security.cert} package.
- * @since Android 1.0
*/
@Deprecated
public abstract class IdentityScope extends Identity {
@@ -49,8 +37,6 @@
/**
* Constructs a new instance of {@code IdentityScope}.
- *
- * @since Android 1.0
*/
protected IdentityScope() {
super();
@@ -59,10 +45,9 @@
/**
* Constructs a new instance of {@code IdentityScope} with the specified
* name.
- *
+ *
* @param name
* the name of this {@code IdentityScope}.
- * @since Android 1.0
*/
public IdentityScope(String name) {
super(name);
@@ -71,14 +56,13 @@
/**
* Constructs a new instance of {@code IdentityScope} with the specified
* name and the specified scope.
- *
+ *
* @param name
* the name of this {@code IdentityScope}.
* @param scope
* the scope of this {@code IdentityScope}.
* @throws KeyManagementException
* if an identity with the same key already exists.
- * @since Android 1.0
*/
public IdentityScope(String name, IdentityScope scope)
throws KeyManagementException {
@@ -87,9 +71,8 @@
/**
* Returns the system's scope.
- *
+ *
* @return the system's scope.
- * @since Android 1.0
*/
public static IdentityScope getSystemScope() {
/*
@@ -116,10 +99,9 @@
/**
* Sets the system's scope.
- *
+ *
* @param scope
* the scope to set.
- * @since Android 1.0
*/
protected static void setSystemScope(IdentityScope scope) {
SecurityManager sm = System.getSecurityManager();
@@ -131,21 +113,19 @@
/**
* Returns the number of {@code Identity} objects in this scope.
- *
+ *
* @return the number of {@code Identity} objects in this scope.
- * @since Android 1.0
*/
public abstract int size();
/**
* Returns the {@code Identity} with the specified name or {@code null} if
* no {@code Identity} with the specified name is present in this scope.
- *
+ *
* @param name
* the name of the {@code Identity} to be returned.
* @return the {@code Identity} with the specified name or {@code null} if
* not present.
- * @since Android 1.0
*/
public abstract Identity getIdentity(String name);
@@ -153,13 +133,12 @@
* Returns the {@code Identity} with the name of the specified principal or
* {@code null} if no {@code Identity} with the name of the specified
* principal is present in this scope.
- *
+ *
* @param principal
* the {@code Principal} whose name is used to lookup the {@code
* Identity} to be returned.
* @return the {@code Identity} with the specified name or {@code null} if
* not present.
- * @since Android 1.0
*/
public Identity getIdentity(Principal principal) {
return getIdentity(principal.getName());
@@ -169,36 +148,33 @@
* Returns the {@code Identity} which is associated with the specified key
* or {@code null} if no {@code Identity} associated with the specified key
* is present in this scope.
- *
+ *
* @param key
* the {@code PublicKey} of the {@code Identity} to be returned.
* @return the {@code Identity} associated with the specified key or {@code
* null} if not present.
- * @since Android 1.0
*/
public abstract Identity getIdentity(PublicKey key);
/**
* Adds an {@code Identity} to this {@code IdentityScope}.
- *
+ *
* @param identity
* the {@code Identity} to be added.
* @throws KeyManagementException
* if the specified {@code Identity} is invalid or an identity
* with the same key already exists.
- * @since Android 1.0
*/
public abstract void addIdentity(Identity identity)
throws KeyManagementException;
/**
* Removes an {@code Identity} from this {@code IdentityScope}.
- *
+ *
* @param identity
* the {@code Identity} to be removed.
* @throws KeyManagementException
* if the {@code Identity} is not present in this scope.
- * @since Android 1.0
*/
public abstract void removeIdentity(Identity identity)
throws KeyManagementException;
@@ -206,22 +182,21 @@
/**
* Returns an {@code Enumeration} over the {@code Identity} objects in this
* {@code IdentityScope}.
- *
+ *
* @return an {@code Enumeration} over the {@code Identity} objects in this
* {@code IdentityScope}.
- * @since Android 1.0
*/
public abstract Enumeration<Identity> identities();
/**
* Returns a string containing a concise, human-readable description of this
* {@code IdentityScope}.
- *
+ *
* @return a printable representation for this {@code IdentityScope}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- return new StringBuffer(super.toString())
+ return new StringBuilder(super.toString())
.append("[").append(size()).append("]").toString(); //$NON-NLS-1$ //$NON-NLS-2$
}
}
diff --git a/security/src/main/java/java/security/InvalidAlgorithmParameterException.java b/security/src/main/java/java/security/InvalidAlgorithmParameterException.java
index 0d8a607..26d9f97 100644
--- a/security/src/main/java/java/security/InvalidAlgorithmParameterException.java
+++ b/security/src/main/java/java/security/InvalidAlgorithmParameterException.java
@@ -15,31 +15,22 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code InvalidAlgorithmParameterException} indicates the occurrence of
* invalid algorithm parameters.
- *
- * @since Android 1.0
*/
public class InvalidAlgorithmParameterException extends
GeneralSecurityException {
-
private static final long serialVersionUID = 2864672297499471472L;
/**
* Constructs a new instance of {@code InvalidAlgorithmParameterException}
* with the given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public InvalidAlgorithmParameterException(String msg) {
super(msg);
@@ -47,8 +38,6 @@
/**
* Constructs a new instance of {@code InvalidAlgorithmParameterException}.
- *
- * @since Android 1.0
*/
public InvalidAlgorithmParameterException() {
}
@@ -56,12 +45,11 @@
/**
* Constructs a new instance of {@code InvalidAlgorithmParameterException} with the
* given message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public InvalidAlgorithmParameterException(String message, Throwable cause) {
super(message, cause);
@@ -70,10 +58,9 @@
/**
* Constructs a new instance of {@code InvalidAlgorithmParameterException}
* with the cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public InvalidAlgorithmParameterException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/InvalidKeyException.java b/security/src/main/java/java/security/InvalidKeyException.java
index 95d864e..f08fc51 100644
--- a/security/src/main/java/java/security/InvalidKeyException.java
+++ b/security/src/main/java/java/security/InvalidKeyException.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code InvalidKeyException} indicates exceptional conditions, caused by an
* invalid key.
- *
- * @since Android 1.0
*/
public class InvalidKeyException extends KeyException {
@@ -35,10 +28,9 @@
/**
* Constructs a new instance of {@code InvalidKeyException} with the given
* message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public InvalidKeyException(String msg) {
super(msg);
@@ -46,8 +38,6 @@
/**
* Constructs a new instance of {@code InvalidKeyException}.
- *
- * @since Android 1.0
*/
public InvalidKeyException() {
}
@@ -55,12 +45,11 @@
/**
* Constructs a new instance of {@code InvalidKeyException} with the given
* message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public InvalidKeyException(String message, Throwable cause) {
super(message, cause);
@@ -68,10 +57,9 @@
/**
* Constructs a new instance of {@code InvalidKeyException} with the cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public InvalidKeyException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/InvalidParameterException.java b/security/src/main/java/java/security/InvalidParameterException.java
index ac10448..6ad4645 100644
--- a/security/src/main/java/java/security/InvalidParameterException.java
+++ b/security/src/main/java/java/security/InvalidParameterException.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code InvalidParameterException} indicates exceptional conditions, caused by
* invalid parameters.
- *
- * @since Android 1.0
*/
public class InvalidParameterException extends IllegalArgumentException {
@@ -35,10 +28,9 @@
/**
* Constructs a new instance of {@code InvalidParameterException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public InvalidParameterException(String msg) {
super(msg);
@@ -46,8 +38,6 @@
/**
* Constructs a new instance of {@code InvalidParameterException}.
- *
- * @since Android 1.0
*/
public InvalidParameterException() {
}
diff --git a/security/src/main/java/java/security/Key.java b/security/src/main/java/java/security/Key.java
index 1359ab2..28d24ff 100644
--- a/security/src/main/java/java/security/Key.java
+++ b/security/src/main/java/java/security/Key.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
import java.io.Serializable;
@@ -29,14 +24,11 @@
*
* @see PublicKey
* @see PrivateKey
- * @since Android 1.0
*/
public interface Key extends Serializable {
/**
* The {@code serialVersionUID} to be compatible with JDK1.1.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = 6603384152749567654L;
@@ -46,7 +38,6 @@
*
* @return the name of the algorithm of this key or {@code null} if the
* algorithm is unknown.
- * @since Android 1.0
*/
public String getAlgorithm();
@@ -56,7 +47,6 @@
*
* @return the name of the format used to encode this key, or {@code null}
* if it can not be encoded.
- * @since Android 1.0
*/
public String getFormat();
@@ -66,7 +56,6 @@
*
* @return the encoded form of this key, or {@code null} if encoding is not
* supported by this key.
- * @since Android 1.0
*/
public byte[] getEncoded();
}
diff --git a/security/src/main/java/java/security/KeyException.java b/security/src/main/java/java/security/KeyException.java
index b01f75b..721c896 100644
--- a/security/src/main/java/java/security/KeyException.java
+++ b/security/src/main/java/java/security/KeyException.java
@@ -15,17 +15,10 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code KeyException} is the common superclass of all key related exceptions.
- *
- * @since Android 1.0
*/
public class KeyException extends GeneralSecurityException {
@@ -33,10 +26,9 @@
/**
* Constructs a new instance of {@code KeyException} with the given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public KeyException(String msg) {
super(msg);
@@ -44,8 +36,6 @@
/**
* Constructs a new instance of {@code KeyException}.
- *
- * @since Android 1.0
*/
public KeyException() {
}
@@ -53,12 +43,11 @@
/**
* Constructs a new instance of {@code KeyException} with the given message
* and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public KeyException(String message, Throwable cause) {
super(message, cause);
@@ -66,10 +55,9 @@
/**
* Constructs a new instance of {@code KeyException} with the cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public KeyException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/KeyFactory.java b/security/src/main/java/java/security/KeyFactory.java
index 7c4966f..7484a31 100644
--- a/security/src/main/java/java/security/KeyFactory.java
+++ b/security/src/main/java/java/security/KeyFactory.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.security.spec.InvalidKeySpecException;
@@ -33,8 +28,6 @@
* public and private key objects and convert keys between their external
* representation, that can be easily transported and their internal
* representation.
- *
- * @since Android 1.0
*/
public class KeyFactory {
// The service name.
@@ -63,7 +56,6 @@
* the provider.
* @param algorithm
* the algorithm to use.
- * @since Android 1.0
*/
protected KeyFactory(KeyFactorySpi keyFacSpi,
Provider provider,
@@ -83,7 +75,6 @@
* algorithm.
* @throws NoSuchAlgorithmException
* if no provider provides the requested algorithm.
- * @since Android 1.0
*/
public static KeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -112,16 +103,16 @@
* if the requested provider is not available.
* @throws IllegalArgumentException
* if {@code provider} is {@code null} or empty.
- * @since Android 1.0
*/
+ @SuppressWarnings("nls")
public static KeyFactory getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
if ((provider == null) || (provider.length() == 0)) {
- throw new IllegalArgumentException(Messages.getString("security.02")); //$NON-NLS-1$
+ throw new IllegalArgumentException(Messages.getString("security.02"));
}
Provider p = Security.getProvider(provider);
if (p == null) {
- throw new NoSuchProviderException(Messages.getString("security.03", provider)); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new NoSuchProviderException(Messages.getString("security.03", provider));
}
return getInstance(algorithm, p);
}
@@ -138,7 +129,6 @@
* algorithm from the specified provider.
* @throws NoSuchAlgorithmException
* if the provider does not provide the requested algorithm.
- * @since Android 1.0
*/
public static KeyFactory getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
@@ -158,19 +148,17 @@
* Returns the provider associated with this {@code KeyFactory}.
*
* @return the provider associated with this {@code KeyFactory}.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
}
/**
- * Returns the name of the algorithm associated with this {@code KeyFactory}
- * .
+ * Returns the name of the algorithm associated with this {@code
+ * KeyFactory}.
*
- * @return the name of the algorithm associated with this {@code KeyFactory}
- * .
- * @since Android 1.0
+ * @return the name of the algorithm associated with this {@code
+ * KeyFactory}.
*/
public final String getAlgorithm() {
return algorithm;
@@ -185,7 +173,6 @@
* @return the public key
* @throws InvalidKeySpecException
* if the specified {@code keySpec} is invalid
- * @since Android 1.0
*/
public final PublicKey generatePublic(KeySpec keySpec)
throws InvalidKeySpecException {
@@ -201,7 +188,6 @@
* @return the private key.
* @throws InvalidKeySpecException
* if the specified {@code keySpec} is invalid.
- * @since Android 1.0
*/
public final PrivateKey generatePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
@@ -219,7 +205,6 @@
* @throws InvalidKeySpecException
* if the key can not be processed, or the requested requested
* {@code KeySpec} is inappropriate for the given key.
- * @since Android 1.0
*/
public final <T extends KeySpec> T getKeySpec(Key key,
Class<T> keySpec)
@@ -236,7 +221,6 @@
* @throws InvalidKeyException
* if the specified key can not be translated by this key
* factory.
- * @since Android 1.0
*/
public final Key translateKey(Key key)
throws InvalidKeyException {
diff --git a/security/src/main/java/java/security/KeyFactorySpi.java b/security/src/main/java/java/security/KeyFactorySpi.java
index 7d3154e..0de00b2 100644
--- a/security/src/main/java/java/security/KeyFactorySpi.java
+++ b/security/src/main/java/java/security/KeyFactorySpi.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.security.spec.InvalidKeySpecException;
@@ -30,7 +25,6 @@
* {@link KeyFactory}.
*
* @see KeyFactory
- * @since Android 1.0
*/
public abstract class KeyFactorySpi {
@@ -43,7 +37,6 @@
* @return the public key.
* @throws InvalidKeySpecException
* if the specified {@code keySpec} is invalid.
- * @since Android 1.0
*/
protected abstract PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException;
@@ -57,7 +50,6 @@
* @return the private key.
* @throws InvalidKeySpecException
* if the specified {@code keySpec} is invalid.
- * @since Android 1.0
*/
protected abstract PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException;
@@ -73,7 +65,6 @@
* @throws InvalidKeySpecException
* if the key can not be processed, or the requested requested
* {@code KeySpec} is inappropriate for the given key.
- * @since Android 1.0
*/
protected abstract <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
throws InvalidKeySpecException;
@@ -88,7 +79,6 @@
* @throws InvalidKeyException
* if the specified key can not be translated by this key
* factory.
- * @since Android 1.0
*/
protected abstract Key engineTranslateKey(Key key) throws InvalidKeyException;
diff --git a/security/src/main/java/java/security/KeyManagementException.java b/security/src/main/java/java/security/KeyManagementException.java
index 295ec03..00a5b3c 100644
--- a/security/src/main/java/java/security/KeyManagementException.java
+++ b/security/src/main/java/java/security/KeyManagementException.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code KeyManagementException} is a general exception, thrown to indicate an
* exception during processing an operation concerning key management.
- *
- * @since Android 1.0
*/
public class KeyManagementException extends KeyException {
@@ -35,10 +28,9 @@
/**
* Constructs a new instance of {@code KeyManagementException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public KeyManagementException(String msg) {
super(msg);
@@ -46,8 +38,6 @@
/**
* Constructs a new instance of {@code KeyManagementException}.
- *
- * @since Android 1.0
*/
public KeyManagementException() {
}
@@ -55,12 +45,11 @@
/**
* Constructs a new instance of {@code KeyManagementException} with the
* given message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public KeyManagementException(String message, Throwable cause) {
super(message, cause);
@@ -69,13 +58,12 @@
/**
* Constructs a new instance of {@code KeyManagementException} with the
* cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public KeyManagementException(Throwable cause) {
super(cause);
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/KeyPair.java b/security/src/main/java/java/security/KeyPair.java
index 6399427..b86593b 100644
--- a/security/src/main/java/java/security/KeyPair.java
+++ b/security/src/main/java/java/security/KeyPair.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vladimir N. Molotkov
-* @version $Revision$
-*/
-
package java.security;
import java.io.Serializable;
@@ -30,7 +25,6 @@
*
* @see PrivateKey
* @see PublicKey
- * @since Android 1.0
*/
public final class KeyPair implements Serializable {
@@ -41,12 +35,11 @@
/**
* Constructs a new instance of {@code KeyPair} with a public key and the
* corresponding private key.
- *
+ *
* @param publicKey
* the public key.
* @param privateKey
* the private key.
- * @since Android 1.0
*/
public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
this.privateKey = privateKey;
@@ -55,9 +48,8 @@
/**
* Returns the private key.
- *
+ *
* @return the private key.
- * @since Android 1.0
*/
public PrivateKey getPrivate() {
return privateKey;
@@ -65,9 +57,8 @@
/**
* Returns the public key.
- *
+ *
* @return the public key.
- * @since Android 1.0
*/
public PublicKey getPublic() {
return publicKey;
diff --git a/security/src/main/java/java/security/KeyPairGenerator.java b/security/src/main/java/java/security/KeyPairGenerator.java
index 5682aa2..2a17e98 100644
--- a/security/src/main/java/java/security/KeyPairGenerator.java
+++ b/security/src/main/java/java/security/KeyPairGenerator.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
import java.security.spec.AlgorithmParameterSpec;
@@ -32,9 +27,8 @@
* {@code KeyPairGenerator} is an engine class which is capable of generating a
* private key and its related public key utilizing the algorithm it was
* initialized with.
- *
+ *
* @see KeyPairGeneratorSpi
- * @since Android 1.0
*/
public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
@@ -56,10 +50,9 @@
/**
* Constructs a new instance of {@code KeyPairGenerator} with the name of
* the algorithm to use.
- *
+ *
* @param algorithm
* the name of algorithm to use
- * @since Android 1.0
*/
protected KeyPairGenerator(String algorithm) {
this.algorithm = algorithm;
@@ -67,9 +60,8 @@
/**
* Returns the name of the algorithm of this {@code KeyPairGenerator}.
- *
+ *
* @return the name of the algorithm of this {@code KeyPairGenerator}
- * @since Android 1.0
*/
public String getAlgorithm() {
return algorithm;
@@ -86,7 +78,6 @@
* @throws NoSuchAlgorithmException if the specified algorithm is not available
* @throws NullPointerException
* if {@code algorithm} is {@code null}
- * @since Android 1.0
*/
public static KeyPairGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -101,11 +92,10 @@
result.algorithm = algorithm;
result.provider = engine.provider;
return result;
- } else {
- result = new KeyPairGeneratorImpl((KeyPairGeneratorSpi) engine.spi,
- engine.provider, algorithm);
- return result;
}
+ result = new KeyPairGeneratorImpl((KeyPairGeneratorSpi) engine.spi,
+ engine.provider, algorithm);
+ return result;
}
}
@@ -123,7 +113,6 @@
* @throws NoSuchProviderException if the specified provider is not available
* @throws NullPointerException
* if {@code algorithm} is {@code null}
- * @since Android 1.0
*/
public static KeyPairGenerator getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
@@ -151,7 +140,6 @@
* @throws NoSuchAlgorithmException if the specified algorithm is not available
* @throws NullPointerException
* if {@code algorithm} is {@code null}
- * @since Android 1.0
*/
public static KeyPairGenerator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
@@ -169,19 +157,17 @@
result.algorithm = algorithm;
result.provider = provider;
return result;
- } else {
- result = new KeyPairGeneratorImpl((KeyPairGeneratorSpi) engine.spi,
- provider, algorithm);
- return result;
}
+ result = new KeyPairGeneratorImpl((KeyPairGeneratorSpi) engine.spi,
+ provider, algorithm);
+ return result;
}
}
/**
* Returns the provider associated with this {@code KeyPairGenerator}.
- *
+ *
* @return the provider associated with this {@code KeyPairGenerator}
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -191,10 +177,9 @@
* Initializes this {@code KeyPairGenerator} with the given key size. The
* default parameter set and a default {@code SecureRandom} instance will be
* used.
- *
+ *
* @param keysize
* the size of the key (number of bits)
- * @since Android 1.0
*/
public void initialize(int keysize) {
initialize(keysize, random);
@@ -204,12 +189,11 @@
* Initializes this {@code KeyPairGenerator} with the given {@code
* AlgorithmParameterSpec}. A default {@code SecureRandom} instance will be
* used.
- *
+ *
* @param param
* the parameters to use
* @throws InvalidAlgorithmParameterException
* if the specified parameters are not supported
- * @since Android 1.0
*/
public void initialize(AlgorithmParameterSpec param)
throws InvalidAlgorithmParameterException {
@@ -221,9 +205,8 @@
* is called.
* <p>
* This does exactly the same as {@link #generateKeyPair()}.
- *
+ *
* @return a new unique {@code KeyPair} each time this method is called
- * @since Android 1.0
*/
public final KeyPair genKeyPair() {
return generateKeyPair();
@@ -234,10 +217,10 @@
* is called.
* <p>
* This does exactly the same as {@link #genKeyPair()}.
- *
+ *
* @return a new unique {@code KeyPair} each time this method is called
- * @since Android 1.0
*/
+ @Override
public KeyPair generateKeyPair() {
return null;
}
@@ -245,28 +228,28 @@
/**
* Initializes this {@code KeyPairGenerator} with the given key size and the
* given {@code SecureRandom}. The default parameter set will be used.
- *
+ *
* @param keysize
* the key size
* @param random
* the source of randomness
- * @since Android 1.0
*/
+ @Override
public void initialize(int keysize, SecureRandom random) {
}
/**
* Initializes this {@code KeyPairGenerator} with the given {@code
* AlgorithmParameterSpec} and the given {@code SecureRandom}.
- *
+ *
* @param param
* the parameters to use
* @param random
* the source of randomness
* @throws InvalidAlgorithmParameterException
* if the specified parameters are not supported
- * @since Android 1.0
*/
+ @Override
public void initialize(AlgorithmParameterSpec param, SecureRandom random)
throws InvalidAlgorithmParameterException {
}
@@ -294,18 +277,21 @@
// implementation of initialize(int keysize, SecureRandom random)
// using corresponding spi initialize() method
+ @Override
public void initialize(int keysize, SecureRandom random) {
spiImpl.initialize(keysize, random);
}
// implementation of generateKeyPair()
// using corresponding spi generateKeyPair() method
+ @Override
public KeyPair generateKeyPair() {
return spiImpl.generateKeyPair();
}
// implementation of initialize(int keysize, SecureRandom random)
// using corresponding spi initialize() method
+ @Override
public void initialize(AlgorithmParameterSpec param, SecureRandom random)
throws InvalidAlgorithmParameterException {
spiImpl.initialize(param, random);
@@ -313,4 +299,4 @@
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/KeyPairGeneratorSpi.java b/security/src/main/java/java/security/KeyPairGeneratorSpi.java
index 272c305..e2e22c1 100644
--- a/security/src/main/java/java/security/KeyPairGeneratorSpi.java
+++ b/security/src/main/java/java/security/KeyPairGeneratorSpi.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
import java.security.spec.AlgorithmParameterSpec;
@@ -31,14 +26,10 @@
* definition for {@link KeyPairGenerator}.
*
* @see KeyPairGenerator
- * @since Android 1.0
*/
public abstract class KeyPairGeneratorSpi {
-
/**
* Constructs a new instance of {@code KeyPairGeneratorSpi}.
- *
- * @since Android 1.0
*/
public KeyPairGeneratorSpi() {
}
@@ -46,38 +37,35 @@
/**
* Computes and returns a new unique {@code KeyPair} each time this method
* is called.
- *
+ *
* @return a new unique {@code KeyPair} each time this method is called.
- * @since Android 1.0
*/
public abstract KeyPair generateKeyPair();
/**
* Initializes this {@code KeyPairGeneratorSpi} with the given key size and
* the given {@code SecureRandom}. The default parameter set will be used.
- *
+ *
* @param keysize
* the key size (number of bits).
* @param random
* the source of randomness.
- * @since Android 1.0
*/
public abstract void initialize(int keysize, SecureRandom random);
/**
* Initializes this {@code KeyPairGeneratorSpi} with the given {@code
* AlgorithmParameterSpec} and the given {@code SecureRandom}.
- *
+ *
* @param params
* the parameters to use.
* @param random
* the source of randomness.
* @throws InvalidAlgorithmParameterException
* if the specified parameters are not supported.
- * @since Android 1.0
*/
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException {
throw new UnsupportedOperationException(Messages.getString("security.2E")); //$NON-NLS-1$
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/KeyRep.java b/security/src/main/java/java/security/KeyRep.java
index ec1d364..29ccd22 100644
--- a/security/src/main/java/java/security/KeyRep.java
+++ b/security/src/main/java/java/security/KeyRep.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vladimir N. Molotkov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
@@ -38,8 +33,6 @@
/**
* {@code KeyRep} is a standardized representation for serialized {@link Key}
* objects.
- *
- * @since Android 1.0
*/
public class KeyRep implements Serializable {
@@ -57,7 +50,7 @@
* Constructs a new instance of {@code KeyRep} with the specified arguments.
* The arguments should be obtained from the {@code Key} object that has to
* be serialized.
- *
+ *
* @param type
* the type of the key.
* @param algorithm
@@ -70,7 +63,6 @@
* @throws NullPointerException
* if {@code type, algorithm, format or encoded} is {@code null}
* .
- * @since Android 1.0
*/
public KeyRep(Type type,
String algorithm, String format, byte[] encoded) {
@@ -107,12 +99,11 @@
* initialized with a {@link X509EncodedKeySpec} using the encoded key
* bytes.
* </ul>
- *
+ *
* @return the resolved {@code Key} object.
* @throws ObjectStreamException
* if the {@code Type}|format combination is not recognized, or
* the resolution of any key parameter fails.
- * @since Android 1.0
*/
protected Object readResolve() throws ObjectStreamException {
switch (type) {
@@ -174,10 +165,8 @@
/**
* {@code Type} enumerates the supported key types.
- * @since Android 1.0
*/
public static enum Type {
-
/**
* Type for secret keys.
*/
diff --git a/security/src/main/java/java/security/KeyStore.java b/security/src/main/java/java/security/KeyStore.java
index 699a9df..02ac01d 100644
--- a/security/src/main/java/java/security/KeyStore.java
+++ b/security/src/main/java/java/security/KeyStore.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
import java.io.File;
@@ -29,6 +24,7 @@
import java.io.OutputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
@@ -46,14 +42,12 @@
* {@code KeyStore} is responsible for maintaining cryptographic keys and their
* owners.
* <p>
- * The type of the system key store can be changed by setting the {@code
+ * The type of the system key store can be changed by setting the {@code
* 'keystore.type'} property in the file named {@code
* JAVA_HOME/lib/security/java.security}.
- * </p>
- *
+ *
* @see Certificate
* @see PrivateKey
- * @since Android 1.0
*/
public class KeyStore {
@@ -88,14 +82,13 @@
/**
* Constructs a new instance of {@code KeyStore} with the given arguments.
- *
+ *
* @param keyStoreSpi
* the concrete key store.
* @param provider
* the provider.
* @param type
* the type of the {@code KeyStore} to be constructed.
- * @since Android 1.0
*/
protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type) {
this.type = type;
@@ -118,7 +111,7 @@
/**
* Returns a new instance of {@code KeyStore} with the specified type.
- *
+ *
* @param type
* the type of the returned {@code KeyStore}.
* @return a new instance of {@code KeyStore} with the specified type.
@@ -128,7 +121,6 @@
* @throws NullPointerException
* if {@code type} is {@code null}.
* @see #getDefaultType
- * @since Android 1.0
*/
public static KeyStore getInstance(String type) throws KeyStoreException {
if (type == null) {
@@ -147,7 +139,7 @@
/**
* Returns a new instance of {@code KeyStore} from the specified provider
* with the given type.
- *
+ *
* @param type
* the type of the returned {@code KeyStore}.
* @param provider
@@ -161,8 +153,10 @@
* if the specified provider is not available.
* @throws IllegalArgumentException
* if {@code provider} is {@code null} or the empty string.
+ * @throws NullPointerException
+ * if {@code type} is {@code null} (instead of
+ * NoSuchAlgorithmException) as in 1.4 release
* @see #getDefaultType
- * @since Android 1.0
*/
public static KeyStore getInstance(String type, String provider)
throws KeyStoreException, NoSuchProviderException {
@@ -183,7 +177,7 @@
/**
* Returns a new instance of {@code KeyStore} from the specified provider
* with the given type.
- *
+ *
* @param type
* the type of the returned {@code KeyStore}.
* @param provider
@@ -195,8 +189,10 @@
* KeyStore}.
* @throws IllegalArgumentException
* if {@code provider} is {@code null} or the empty string.
+ * @throws NullPointerException
+ * if {@code type} is {@code null} (instead of
+ * NoSuchAlgorithmException) as in 1.4 release
* @see #getDefaultType
- * @since Android 1.0
*/
public static KeyStore getInstance(String type, Provider provider)
throws KeyStoreException {
@@ -225,10 +221,8 @@
* The default is specified in the {@code 'keystore.type'} property in the
* file named {@code JAVA_HOME/lib/security/java.security}. If this property
* is not set, {@code "jks"} will be used.
- * </p>
- *
+ *
* @return the default type for {@code KeyStore} instances
- * @since Android 1.0
*/
public static final String getDefaultType() {
String dt = AccessController.doPrivileged(
@@ -243,9 +237,8 @@
/**
* Returns the provider associated with this {@code KeyStore}.
- *
+ *
* @return the provider associated with this {@code KeyStore}.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -253,9 +246,8 @@
/**
* Returns the type of this {@code KeyStore}.
- *
+ *
* @return the type of this {@code KeyStore}.
- * @since Android 1.0
*/
public final String getType() {
return type;
@@ -264,7 +256,7 @@
/**
* Returns the key with the given alias, using the password to recover the
* key from the store.
- *
+ *
* @param alias
* the alias for the entry.
* @param password
@@ -277,7 +269,6 @@
* if the algorithm for recovering the key is not available.
* @throws UnrecoverableKeyException
* if the key can not be recovered.
- * @since Android 1.0
*/
public final Key getKey(String alias, char[] password)
throws KeyStoreException, NoSuchAlgorithmException,
@@ -292,14 +283,13 @@
/**
* Returns the certificate chain for the entry with the given alias.
- *
+ *
* @param alias
* the alias for the entry.
* @return the certificate chain for the entry with the given alias, or
* {@code null} if the specified alias is not bound to an entry.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public final Certificate[] getCertificateChain(String alias)
throws KeyStoreException {
@@ -313,14 +303,13 @@
/**
* Returns the trusted certificate for the entry with the given alias.
- *
+ *
* @param alias
* the alias for the entry.
* @return the trusted certificate for the entry with the given alias, or
* {@code null} if the specified alias is not bound to an entry.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public final Certificate getCertificate(String alias)
throws KeyStoreException {
@@ -334,14 +323,13 @@
/**
* Returns the creation date of the entry with the given alias.
- *
+ *
* @param alias
* the alias for the entry.
* @return the creation date, or {@code null} if the specified alias is not
* bound to an entry.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public final Date getCreationDate(String alias) throws KeyStoreException {
if (!isInit) {
@@ -356,8 +344,7 @@
* Associates the given alias with the key, password and certificate chain.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
- *
+ *
* @param alias
* the alias for the key.
* @param key
@@ -371,7 +358,8 @@
* @throws IllegalArgumentException
* if {@code key} is a {@code PrivateKey} and {@code chain} does
* not contain any certificates.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final void setKeyEntry(String alias, Key key, char[] password,
Certificate[] chain) throws KeyStoreException {
@@ -394,13 +382,11 @@
* Associates the given alias with a key and a certificate chain.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
* <p>
* If this {@code KeyStore} is of type {@code "jks"}, {@code key} must be
* encoded conform to the PKS#8 standard as an
* {@link javax.crypto.EncryptedPrivateKeyInfo}.
- * </p>
- *
+ *
* @param alias
* the alias for the key.
* @param key
@@ -408,11 +394,13 @@
* @param chain
* the certificate chain.
* @throws KeyStoreException
- * if this {@code KeyStore} is not initialized.
+ * if this {@code KeyStore} is not initialized or if {@code key}
+ * is null.
* @throws IllegalArgumentException
* if {@code key} is a {@code PrivateKey} and {@code chain}
* does.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final void setKeyEntry(String alias, byte[] key, Certificate[] chain)
throws KeyStoreException {
@@ -428,8 +416,7 @@
* Associates the given alias with a certificate.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
- *
+ *
* @param alias
* the alias for the certificate.
* @param cert
@@ -438,7 +425,8 @@
* if this {@code KeyStore} is not initialized, or an existing
* alias is not associated to an entry containing a trusted
* certificate, or this method fails for any other reason.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final void setCertificateEntry(String alias, Certificate cert)
throws KeyStoreException {
@@ -453,32 +441,35 @@
/**
* Deletes the entry identified with the given alias from this {@code
* KeyStore}.
- *
+ *
* @param alias
* the alias for the entry.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized, or if the entry
* can not be deleted.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final void deleteEntry(String alias) throws KeyStoreException {
- // BEGIN android-changed
if (!isInit) {
+ // BEGIN android-changed
throwNotInitialized();
+ // END android-changed
}
- // END android-changed
+ if (alias == null) {
+ throw new NullPointerException(Messages.getString("security.3F")); //$NON-NLS-1$
+ }
implSpi.engineDeleteEntry(alias);
}
/**
* Returns an {@code Enumeration} over all alias names stored in this
* {@code KeyStore}.
- *
+ *
* @return an {@code Enumeration} over all alias names stored in this
* {@code KeyStore}.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public final Enumeration<String> aliases() throws KeyStoreException {
if (!isInit) {
@@ -491,13 +482,14 @@
/**
* Indicates whether the given alias is present in this {@code KeyStore}.
- *
+ *
* @param alias
* the alias of an entry.
* @return {@code true} if the alias exists, {@code false} otherwise.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final boolean containsAlias(String alias) throws KeyStoreException {
if (!isInit) {
@@ -513,11 +505,10 @@
/**
* Returns the number of entries stored in this {@code KeyStore}.
- *
+ *
* @return the number of entries stored in this {@code KeyStore}.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public final int size() throws KeyStoreException {
if (!isInit) {
@@ -531,56 +522,63 @@
/**
* Indicates whether the specified alias is associated with either a
* {@link PrivateKeyEntry} or a {@link SecretKeyEntry}.
- *
+ *
* @param alias
* the alias of an entry.
* @return {@code true} if the given alias is associated with a key entry.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final boolean isKeyEntry(String alias) throws KeyStoreException {
- // BEGIN android-changed
if (!isInit) {
+ // BEGIN android-changed
throwNotInitialized();
+ // END android-changed
}
- // END android-changed
+ if (alias == null) {
+ throw new NullPointerException(Messages.getString("security.3F")); //$NON-NLS-1$
+ }
return implSpi.engineIsKeyEntry(alias);
}
/**
* Indicates whether the specified alias is associated with a
* {@link TrustedCertificateEntry}.
- *
+ *
* @param alias
* the alias of an entry.
* @return {@code true} if the given alias is associated with a certificate
* entry.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final boolean isCertificateEntry(String alias)
throws KeyStoreException {
- // BEGIN android-changed
if (!isInit) {
+ // BEGIN android-changed
throwNotInitialized();
+ // END android-changed
}
- // END android-changed
+ if (alias == null) {
+ throw new NullPointerException(Messages.getString("security.3F")); //$NON-NLS-1$
+ }
return implSpi.engineIsCertificateEntry(alias);
}
/**
* Returns the alias associated with the first entry whose certificate
* matches the specified certificate.
- *
+ *
* @param cert
* the certificate to find the associated entry's alias for.
* @return the alias or {@code null} if no entry with the specified
* certificate can be found.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public final String getCertificateAlias(Certificate cert)
throws KeyStoreException {
@@ -596,7 +594,7 @@
* Writes this {@code KeyStore} to the specified {@code OutputStream}. The
* data written to the {@code OutputStream} is protected by the specified
* password.
- *
+ *
* @param stream
* the {@code OutputStream} to write the store's data to.
* @param password
@@ -610,7 +608,6 @@
* @throws CertificateException
* if an exception occurred while storing the certificates of
* this {@code KeyStore}.
- * @since Android 1.0
*/
public final void store(OutputStream stream, char[] password)
throws KeyStoreException, IOException, NoSuchAlgorithmException,
@@ -620,23 +617,15 @@
throwNotInitialized();
// END android-changed
}
- // BEGIN android-removed
- // copied from a newer version of harmony
- // Just delegate stream and password to implSpi
- // if (stream == null) {
- // throw new IOException(Messages.getString("security.51")); //$NON-NLS-1$
- // }
- // if (password == null) {
- // throw new IOException(Messages.getString("security.50")); //$NON-NLS-1$
- // }
- // END android-removed
+
+ //Just delegate stream and password to implSpi
implSpi.engineStore(stream, password);
}
/**
* Stores this {@code KeyStore} using the specified {@code
* LoadStoreParameter}.
- *
+ *
* @param param
* the {@code LoadStoreParameter} that specifies how to store
* this {@code KeyStore}, maybe {@code null}.
@@ -651,7 +640,6 @@
* this {@code KeyStore}.
* @throws IllegalArgumentException
* if the given {@link LoadStoreParameter} is not recognized.
- * @since Android 1.0
*/
public final void store(LoadStoreParameter param) throws KeyStoreException,
IOException, NoSuchAlgorithmException, CertificateException {
@@ -669,7 +657,7 @@
* {@code KeyStore} or to initialize a {@code KeyStore} which does not rely
* on an {@code InputStream}. This {@code KeyStore} utilizes the given
* password to verify the stored data.
- *
+ *
* @param stream
* the {@code InputStream} to load this {@code KeyStore}'s data
* from or {@code null}.
@@ -682,7 +670,6 @@
* @throws CertificateException
* if an exception occurred while loading the certificates of
* this {@code KeyStore}.
- * @since Android 1.0
*/
public final void load(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException {
@@ -693,7 +680,7 @@
/**
* Loads this {@code KeyStore} using the specified {@code
* LoadStoreParameter}.
- *
+ *
* @param param
* the {@code LoadStoreParameter} that specifies how to load this
* {@code KeyStore}, maybe {@code null}.
@@ -706,7 +693,6 @@
* this {@code KeyStore}.
* @throws IllegalArgumentException
* if the given {@link LoadStoreParameter} is not recognized.
- * @since Android 1.0
*/
public final void load(LoadStoreParameter param) throws IOException,
NoSuchAlgorithmException, CertificateException {
@@ -717,7 +703,7 @@
/**
* Returns the {@code Entry} with the given alias, using the specified
* {@code ProtectionParameter}.
- *
+ *
* @param alias
* the alias of the requested entry.
* @param param
@@ -731,7 +717,8 @@
* if the entry can not be recovered.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null}.
*/
public final Entry getEntry(String alias, ProtectionParameter param)
throws NoSuchAlgorithmException, UnrecoverableEntryException,
@@ -753,8 +740,7 @@
* specified {@code ProtectionParameter}.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
- *
+ *
* @param alias
* the alias for the entry.
* @param entry
@@ -763,7 +749,9 @@
* the {@code ProtectionParameter} to protect the entry.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code alias} is {@code null} or {@code entry} is {@code
+ * null}.
*/
public final void setEntry(String alias, Entry entry,
ProtectionParameter param) throws KeyStoreException {
@@ -784,7 +772,7 @@
/**
* Indicates whether the entry for the given alias is assignable to the
* provided {@code Class}.
- *
+ *
* @param alias
* the alias for the entry.
* @param entryClass
@@ -793,7 +781,6 @@
* the specified {@code entryClass}.
* @throws KeyStoreException
* if this {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public final boolean entryInstanceOf(String alias,
Class<? extends KeyStore.Entry> entryClass)
@@ -815,25 +802,20 @@
/**
* {@code Builder} is used to construct new instances of {@code KeyStore}.
- *
- * @since Android 1.0
*/
public abstract static class Builder {
/**
* Constructs a new instance of {@code Builder}.
- *
- * @since Android 1.0
*/
protected Builder() {
}
/**
* Returns the {@code KeyStore} created by this {@code Builder}.
- *
+ *
* @return the {@code KeyStore} created by this {@code Builder}.
* @throws KeyStoreException
* if an error occurred during construction.
- * @since Android 1.0
*/
public abstract KeyStore getKeyStore() throws KeyStoreException;
@@ -841,7 +823,7 @@
* Returns the {@code ProtectionParameter} to be used when a {@code
* Entry} with the specified alias is requested. Before this method is
* invoked, {@link #getKeyStore()} must be called.
- *
+ *
* @param alias
* the alias for the entry.
* @return the {@code ProtectionParameter} to be used when a {@code
@@ -854,18 +836,14 @@
* invocation of this method.
* @throws NullPointerException
* if {@code alias} is {@code null}.
- * @since Android 1.0
*/
public abstract ProtectionParameter getProtectionParameter(String alias)
throws KeyStoreException;
- // BEGIN android-note
- // renamed parameter
- // END android-note
/**
* Returns a new {@code Builder} that holds the given {@code KeyStore}
* and the given {@code ProtectionParameter}.
- *
+ *
* @param keyStore
* the {@code KeyStore} to be held.
* @param protectionParameter
@@ -878,7 +856,6 @@
* {@code null}.
* @throws IllegalArgumentException
* if the given {@code KeyStore} is not initialized.
- * @since Android 1.0
*/
public static Builder newInstance(KeyStore keyStore,
ProtectionParameter protectionParameter) {
@@ -903,8 +880,7 @@
* If {@code provider} is {@code null}, all installed providers are
* searched, otherwise the key store from the specified provider is
* used.
- * </p>
- *
+ *
* @param type
* the type of the {@code KeyStore} to be constructed.
* @param provider
@@ -926,7 +902,6 @@
* {@code PasswordProtection} or {@code
* CallbackHandlerProtection}, {@code file} is not a file or
* does not exist at all.
- * @since Android 1.0
*/
public static Builder newInstance(String type, Provider provider,
File file, ProtectionParameter protectionParameter) {
@@ -965,8 +940,7 @@
* If {@code provider} is {@code null}, all installed providers are
* searched, otherwise the key store from the specified provider is
* used.
- * </p>
- *
+ *
* @param type
* the type of the {@code KeyStore} to be constructed.
* @param provider
@@ -985,7 +959,6 @@
* {@code PasswordProtection} or {@code
* CallbackHandlerProtection}, {@code file} is not a file or
* does not exist at all.
- * @since Android 1.0
*/
public static Builder newInstance(String type, Provider provider,
ProtectionParameter protectionParameter) {
@@ -1062,6 +1035,7 @@
//
// Result KeyStore object is returned.
//
+ @Override
public synchronized KeyStore getKeyStore() throws KeyStoreException {
// If KeyStore was created but in final block some exception was
// thrown
@@ -1121,8 +1095,7 @@
isGetKeyStore = true;
- keyStore = ks;
- return keyStore;
+ return ks;
} catch (KeyStoreException e) {
// Store exception
throw lastException = e;
@@ -1139,6 +1112,7 @@
// Return: ProtectionParameter to get Entry which was saved in
// KeyStore with defined alias
//
+ @Override
public synchronized ProtectionParameter getProtectionParameter(
String alias) throws KeyStoreException {
if (alias == null) {
@@ -1151,13 +1125,8 @@
}
}
- // BEGIN android-note
- // Added "static" to the class declaration below.
- // END android-note
/*
* Implementation of LoadStoreParameter interface
- *
- * @author Vera Petrashkova
*/
private static class TmpLSParameter implements LoadStoreParameter {
@@ -1166,6 +1135,7 @@
/**
* Creates TmpLoadStoreParameter object
+ * @param protPar protection parameter
*/
public TmpLSParameter(ProtectionParameter protPar) {
this.protPar = protPar;
@@ -1183,8 +1153,6 @@
/**
* {@code CallbackHandlerProtection} is a {@code ProtectionParameter} that
* encapsulates a {@link CallbackHandler}.
- *
- * @since Android 1.0
*/
public static class CallbackHandlerProtection implements
ProtectionParameter {
@@ -1194,12 +1162,11 @@
/**
* Constructs a new instance of {@code CallbackHandlerProtection} with
* the {@code CallbackHandler}.
- *
+ *
* @param handler
* the {@code CallbackHandler}.
* @throws NullPointerException
* if {@code handler} is {@code null}.
- * @since Android 1.0
*/
public CallbackHandlerProtection(CallbackHandler handler) {
if (handler == null) {
@@ -1210,9 +1177,8 @@
/**
* Returns the {@code CallbackHandler}.
- *
+ *
* @return the {@code CallbackHandler}.
- * @since Android 1.0
*/
public CallbackHandler getCallbackHandler() {
return callbackHandler;
@@ -1222,8 +1188,6 @@
/**
* {@code Entry} is the common marker interface for a {@code KeyStore}
* entry.
- *
- * @since Android 1.0
*/
public static interface Entry {
}
@@ -1231,19 +1195,17 @@
/**
* {@code LoadStoreParameter} represents a parameter that specifies how a
* {@code KeyStore} can be loaded and stored.
- *
+ *
* @see KeyStore#load(LoadStoreParameter)
* @see KeyStore#store(LoadStoreParameter)
- * @since Android 1.0
*/
public static interface LoadStoreParameter {
/**
* Returns the {@code ProtectionParameter} which is used to protect data
* in the {@code KeyStore}.
- *
+ *
* @return the {@code ProtectionParameter} which is used to protect data
* in the {@code KeyStore}, maybe {@code null}.
- * @since Android 1.0
*/
public ProtectionParameter getProtectionParameter();
}
@@ -1251,8 +1213,6 @@
/**
* {@code PasswordProtection} is a {@code ProtectionParameter} that protects
* a {@code KeyStore} using a password.
- *
- * @since Android 1.0
*/
public static class PasswordProtection implements ProtectionParameter,
Destroyable {
@@ -1266,27 +1226,22 @@
* Constructs a new instance of {@code PasswordProtection} with a
* password. A copy of the password is stored in the new {@code
* PasswordProtection} object.
- *
+ *
* @param password
* the password, maybe {@code null}.
- * @since Android 1.0
*/
public PasswordProtection(char[] password) {
- // BEGIN android-changed
- // copied from a newer version of harmony
- if (password != null) {
- this.password = password.clone();
- }
- // END android-changed
+ if (password != null) {
+ this.password = password.clone();
+ }
}
/**
* Returns the password.
- *
+ *
* @return the password.
* @throws IllegalStateException
* if the password has been destroyed.
- * @since Android 1.0
*/
public synchronized char[] getPassword() {
if (isDestroyed) {
@@ -1297,10 +1252,9 @@
/**
* Destroys / invalidates the password.
- *
+ *
* @throws DestroyFailedException
* if the password could not be invalidated.
- * @since Android 1.0
*/
public synchronized void destroy() throws DestroyFailedException {
isDestroyed = true;
@@ -1312,10 +1266,9 @@
/**
* Indicates whether the password is invalidated.
- *
+ *
* @return {@code true} if the password is invalidated, {@code false}
* otherwise.
- * @since Android 1.0
*/
public synchronized boolean isDestroyed() {
return isDestroyed;
@@ -1326,8 +1279,6 @@
* {@code ProtectionParameter} is a marker interface for protection
* parameters. A protection parameter is used to protect the content of a
* {@code KeyStore}.
- *
- * @since Android 1.0
*/
public static interface ProtectionParameter {
}
@@ -1335,8 +1286,6 @@
/**
* {@code PrivateKeyEntry} represents a {@code KeyStore} entry that
* holds a private key.
- *
- * @since Android 1.0
*/
public static final class PrivateKeyEntry implements Entry {
// Store Certificate chain
@@ -1348,7 +1297,7 @@
/**
* Constructs a new instance of {@code PrivateKeyEntry} with the given
* {@code PrivateKey} and the provided certificate chain.
- *
+ *
* @param privateKey
* the private key.
* @param chain
@@ -1361,7 +1310,6 @@
* private key does not match the algorithm of the public
* key of the first certificate or the certificates are not
* all of the same type.
- * @since Android 1.0
*/
public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) {
if (privateKey == null) {
@@ -1389,18 +1337,29 @@
}
}
// clone chain - this.chain = (Certificate[])chain.clone();
- // BEGIN android-changed
- this.chain = new Certificate[chain.length];
- // END android-changed
+ boolean isAllX509Certificates = true;
+ // assert chain length > 0
+ for(Certificate cert: chain){
+ if(!(cert instanceof X509Certificate)){
+ isAllX509Certificates = false;
+ break;
+ }
+ }
+
+ if(isAllX509Certificates){
+ this.chain = new X509Certificate[chain.length];
+ }
+ else{
+ this.chain = new Certificate[chain.length];
+ }
System.arraycopy(chain, 0, this.chain, 0, chain.length);
this.privateKey = privateKey;
}
/**
* Returns the private key.
- *
+ *
* @return the private key.
- * @since Android 1.0
*/
public PrivateKey getPrivateKey() {
return privateKey;
@@ -1408,22 +1367,17 @@
/**
* Returns the certificate chain.
- *
+ *
* @return the certificate chain.
- * @since Android 1.0
*/
public Certificate[] getCertificateChain() {
- // BEGIN android-changed
- // copied from a newer version of harmony
return chain.clone();
- // END android-changed
}
/**
* Returns the certificate corresponding to the private key.
- *
+ *
* @return the certificate corresponding to the private key.
- * @since Android 1.0
*/
public Certificate getCertificate() {
return chain[0];
@@ -1432,12 +1386,12 @@
/**
* Returns a string containing a concise, human-readable description of
* this {@code PrivateKeyEntry}.
- *
+ *
* @return a printable representation for this {@code PrivateKeyEntry}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer sb = new StringBuffer(
+ StringBuilder sb = new StringBuilder(
"PrivateKeyEntry: number of elements in certificate chain is "); //$NON-NLS-1$
sb.append(Integer.toString(chain.length));
sb.append("\n"); //$NON-NLS-1$
@@ -1452,8 +1406,6 @@
/**
* {@code SecretKeyEntry} represents a {@code KeyStore} entry that
* holds a secret key.
- *
- * @since Android 1.0
*/
public static final class SecretKeyEntry implements Entry {
@@ -1463,12 +1415,11 @@
/**
* Constructs a new instance of {@code SecretKeyEntry} with the given
* {@code SecretKey}.
- *
+ *
* @param secretKey
* the secret key.
* @throws NullPointerException
* if {@code secretKey} is {@code null}.
- * @since Android 1.0
*/
public SecretKeyEntry(SecretKey secretKey) {
if (secretKey == null) {
@@ -1479,9 +1430,8 @@
/**
* Returns the secret key.
- *
+ *
* @return the secret key.
- * @since Android 1.0
*/
public SecretKey getSecretKey() {
return secretKey;
@@ -1490,13 +1440,13 @@
/**
* Returns a string containing a concise, human-readable description of
* this {@code SecretKeyEntry}.
- *
+ *
* @return a printable representation for this {@code
* SecretKeyEntry}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer sb = new StringBuffer("SecretKeyEntry: algorithm - "); //$NON-NLS-1$
+ StringBuilder sb = new StringBuilder("SecretKeyEntry: algorithm - "); //$NON-NLS-1$
sb.append(secretKey.getAlgorithm());
return sb.toString();
}
@@ -1505,8 +1455,6 @@
/**
* {@code TrustedCertificateEntry} represents a {@code KeyStore} entry that
* holds a trusted certificate.
- *
- * @since Android 1.0
*/
public static final class TrustedCertificateEntry implements Entry {
@@ -1516,12 +1464,11 @@
/**
* Constructs a new instance of {@code TrustedCertificateEntry} with the
* given {@code Certificate}.
- *
+ *
* @param trustCertificate
* the trusted certificate.
* @throws NullPointerException
* if {@code trustCertificate} is {@code null}.
- * @since Android 1.0
*/
public TrustedCertificateEntry(Certificate trustCertificate) {
if (trustCertificate == null) {
@@ -1532,9 +1479,8 @@
/**
* Returns the trusted certificate.
- *
+ *
* @return the trusted certificate.
- * @since Android 1.0
*/
public Certificate getTrustedCertificate() {
return trustCertificate;
@@ -1543,11 +1489,11 @@
/**
* Returns a string containing a concise, human-readable description of
* this {@code TrustedCertificateEntry}.
- *
+ *
* @return a printable representation for this {@code
* TrustedCertificateEntry}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
return "Trusted certificate entry:\n" + trustCertificate; //$NON-NLS-1$
}
diff --git a/security/src/main/java/java/security/KeyStoreException.java b/security/src/main/java/java/security/KeyStoreException.java
index 7c697f7..4327f7f 100644
--- a/security/src/main/java/java/security/KeyStoreException.java
+++ b/security/src/main/java/java/security/KeyStoreException.java
@@ -15,18 +15,12 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code KeyStoreException} is a general {@code KeyStore} exception.
*
* @see KeyStore
- * @since Android 1.0
*/
public class KeyStoreException extends GeneralSecurityException {
@@ -35,10 +29,9 @@
/**
* Constructs a new instance of {@code KeyStoreException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public KeyStoreException(String msg) {
super(msg);
@@ -46,8 +39,6 @@
/**
* Constructs a new instance of {@code KeyStoreException}.
- *
- * @since Android 1.0
*/
public KeyStoreException() {
}
@@ -55,12 +46,11 @@
/**
* Constructs a new instance of {@code KeyStoreException} with the
* given message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public KeyStoreException(String message, Throwable cause) {
super(message, cause);
@@ -69,10 +59,9 @@
/**
* Constructs a new instance of {@code KeyStoreException} with the
* cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public KeyStoreException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/KeyStoreSpi.java b/security/src/main/java/java/security/KeyStoreSpi.java
index b02f264..e884123 100644
--- a/security/src/main/java/java/security/KeyStoreSpi.java
+++ b/security/src/main/java/java/security/KeyStoreSpi.java
@@ -33,16 +33,15 @@
/**
* {@code KeyStoreSpi} is the Service Provider Interface (SPI) definition for
* {@link KeyStore}.
- *
+ *
* @see KeyStore
- * @since Android 1.0
*/
public abstract class KeyStoreSpi {
/**
* Returns the key with the given alias, using the password to recover the
* key from the store.
- *
+ *
* @param alias
* the alias for the entry.
* @param password
@@ -53,41 +52,37 @@
* if the algorithm for recovering the key is not available.
* @throws UnrecoverableKeyException
* if the key can not be recovered.
- * @since Android 1.0
*/
public abstract Key engineGetKey(String alias, char[] password)
throws NoSuchAlgorithmException, UnrecoverableKeyException;
/**
* Returns the certificate chain for the entry with the given alias.
- *
+ *
* @param alias
* the alias for the entry
* @return the certificate chain for the entry with the given alias, or
* {@code null} if the specified alias is not bound to an entry.
- * @since Android 1.0
*/
public abstract Certificate[] engineGetCertificateChain(String alias);
/**
* Returns the trusted certificate for the entry with the given alias.
- *
+ *
* @param alias
* the alias for the entry.
* @return the trusted certificate for the entry with the given alias, or
* {@code null} if the specified alias is not bound to an entry.
- * @since Android 1.0
*/
public abstract Certificate engineGetCertificate(String alias);
/**
* Returns the creation date of the entry with the given alias.
- *
+ *
* @param alias
* the alias for the entry.
* @return the creation date, or {@code null} if the specified alias is not
* bound to an entry.
- * @since Android 1.0
*/
public abstract Date engineGetCreationDate(String alias);
@@ -95,8 +90,7 @@
* Associates the given alias with the key, password and certificate chain.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
- *
+ *
* @param alias
* the alias for the key.
* @param key
@@ -111,7 +105,6 @@
* @throws IllegalArgumentException
* if {@code key} is a {@code PrivateKey} and {@code chain} does
* not contain any certificates.
- * @since Android 1.0
*/
public abstract void engineSetKeyEntry(String alias, Key key,
char[] password, Certificate[] chain) throws KeyStoreException;
@@ -120,8 +113,7 @@
* Associates the given alias with a key and a certificate chain.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
- *
+ *
* @param alias
* the alias for the key.
* @param key
@@ -133,7 +125,6 @@
* @throws IllegalArgumentException
* if {@code key} is a {@code PrivateKey} and {@code chain}
* does.
- * @since Android 1.0
*/
public abstract void engineSetKeyEntry(String alias, byte[] key,
Certificate[] chain) throws KeyStoreException;
@@ -142,8 +133,7 @@
* Associates the given alias with a certificate.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
- *
+ *
* @param alias
* the alias for the certificate.
* @param cert
@@ -152,7 +142,6 @@
* if an existing alias is not associated to an entry containing
* a trusted certificate, or this method fails for any other
* reason.
- * @since Android 1.0
*/
public abstract void engineSetCertificateEntry(String alias,
Certificate cert) throws KeyStoreException;
@@ -160,12 +149,11 @@
/**
* Deletes the entry identified with the given alias from this {@code
* KeyStoreSpi}.
- *
+ *
* @param alias
* the alias for the entry.
* @throws KeyStoreException
* if the entry can not be deleted.
- * @since Android 1.0
*/
public abstract void engineDeleteEntry(String alias)
throws KeyStoreException;
@@ -173,63 +161,57 @@
/**
* Returns an {@code Enumeration} over all alias names stored in this
* {@code KeyStoreSpi}.
- *
+ *
* @return an {@code Enumeration} over all alias names stored in this
* {@code KeyStoreSpi}.
- * @since Android 1.0
*/
public abstract Enumeration<String> engineAliases();
/**
* Indicates whether the given alias is present in this {@code KeyStoreSpi}.
- *
+ *
* @param alias
* the alias of an entry.
* @return {@code true} if the alias exists, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean engineContainsAlias(String alias);
/**
* Returns the number of entries stored in this {@code KeyStoreSpi}.
- *
+ *
* @return the number of entries stored in this {@code KeyStoreSpi}.
- * @since Android 1.0
*/
public abstract int engineSize();
/**
* Indicates whether the specified alias is associated with either a
* {@link KeyStore.PrivateKeyEntry} or a {@link KeyStore.SecretKeyEntry}.
- *
+ *
* @param alias
* the alias of an entry.
* @return {@code true} if the given alias is associated with a key entry.
- * @since Android 1.0
*/
public abstract boolean engineIsKeyEntry(String alias);
/**
* Indicates whether the specified alias is associated with a
* {@link KeyStore.TrustedCertificateEntry}.
- *
+ *
* @param alias
* the alias of an entry.
* @return {@code true} if the given alias is associated with a certificate
* entry.
- * @since Android 1.0
*/
public abstract boolean engineIsCertificateEntry(String alias);
/**
* Returns the alias associated with the first entry whose certificate
* matches the specified certificate.
- *
+ *
* @param cert
* the certificate to find the associated entry's alias for.
* @return the alias or {@code null} if no entry with the specified
* certificate can be found.
- * @since Android 1.0
*/
public abstract String engineGetCertificateAlias(Certificate cert);
@@ -237,7 +219,7 @@
* Writes this {@code KeyStoreSpi} to the specified {@code OutputStream}.
* The data written to the {@code OutputStream} is protected by the
* specified password.
- *
+ *
* @param stream
* the {@code OutputStream} to write the store's data to.
* @param password
@@ -249,7 +231,6 @@
* @throws CertificateException
* if the an exception occurred while storing the certificates
* of this code {@code KeyStoreSpi}.
- * @since Android 1.0
*/
public abstract void engineStore(OutputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException;
@@ -257,7 +238,7 @@
/**
* Stores this {@code KeyStoreSpi} using the specified {@code
* LoadStoreParameter}.
- *
+ *
* @param param
* the {@code LoadStoreParameter} that specifies how to store
* this {@code KeyStoreSpi}, maybe {@code null}.
@@ -271,7 +252,6 @@
* @throws IllegalArgumentException
* if the given {@link KeyStore.LoadStoreParameter} is not
* recognized.
- * @since Android 1.0
*/
public void engineStore(KeyStore.LoadStoreParameter param)
throws IOException, NoSuchAlgorithmException, CertificateException {
@@ -281,7 +261,7 @@
/**
* Loads this {@code KeyStoreSpi} from the given {@code InputStream}.
* Utilizes the given password to verify the stored data.
- *
+ *
* @param stream
* the {@code InputStream} to load this {@code KeyStoreSpi}'s
* data from.
@@ -294,7 +274,6 @@
* @throws CertificateException
* if the an exception occurred while loading the certificates
* of this code {@code KeyStoreSpi}.
- * @since Android 1.0
*/
public abstract void engineLoad(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException;
@@ -302,7 +281,7 @@
/**
* Loads this {@code KeyStoreSpi} using the specified {@code
* LoadStoreParameter}.
- *
+ *
* @param param
* the {@code LoadStoreParameter} that specifies how to load this
* {@code KeyStoreSpi}, maybe {@code null}.
@@ -316,7 +295,6 @@
* @throws IllegalArgumentException
* if the given {@link KeyStore.LoadStoreParameter} is not
* recognized.
- * @since Android 1.0
*/
public void engineLoad(KeyStore.LoadStoreParameter param)
throws IOException, NoSuchAlgorithmException, CertificateException {
@@ -351,7 +329,7 @@
/**
* Returns the {@code Entry} with the given alias, using the specified
* {@code ProtectionParameter}.
- *
+ *
* @param alias
* the alias of the requested entry.
* @param protParam
@@ -365,7 +343,6 @@
* if the entry can not be recovered.
* @throws KeyStoreException
* if this operation fails
- * @since Android 1.0
*/
public KeyStore.Entry engineGetEntry(String alias,
KeyStore.ProtectionParameter protParam) throws KeyStoreException,
@@ -417,8 +394,7 @@
* specified {@code ProtectionParameter}.
* <p>
* If the specified alias already exists, it will be reassigned.
- * </p>
- *
+ *
* @param alias
* the alias for the entry.
* @param entry
@@ -427,7 +403,6 @@
* the {@code ProtectionParameter} to protect the entry.
* @throws KeyStoreException
* if this operation fails.
- * @since Android 1.0
*/
public void engineSetEntry(String alias, KeyStore.Entry entry,
KeyStore.ProtectionParameter protParam) throws KeyStoreException {
@@ -486,14 +461,13 @@
/**
* Indicates whether the entry for the given alias is assignable to the
* provided {@code Class}.
- *
+ *
* @param alias
* the alias for the entry.
* @param entryClass
* the type of the entry.
* @return {@code true} if the {@code Entry} for the alias is assignable to
* the specified {@code entryClass}.
- * @since Android 1.0
*/
public boolean engineEntryInstanceOf(String alias,
Class<? extends KeyStore.Entry> entryClass) {
diff --git a/security/src/main/java/java/security/MessageDigest.java b/security/src/main/java/java/security/MessageDigest.java
index 97cbdcc..cb8fc08 100644
--- a/security/src/main/java/java/security/MessageDigest.java
+++ b/security/src/main/java/java/security/MessageDigest.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.nio.ByteBuffer;
@@ -31,12 +26,11 @@
* {@code MessageDigest} is an engine class which is capable of generating one
* way hash values for arbitrary input, utilizing the algorithm it was
* initialized with.
- *
+ *
* @see MessageDigestSpi
- * @since Android 1.0
*/
public abstract class MessageDigest extends MessageDigestSpi {
-
+
// The service name
private static final String SERVICE = "MessageDigest"; //$NON-NLS-1$
@@ -55,7 +49,6 @@
*
* @param algorithm
* the name of algorithm to use
- * @since Android 1.0
*/
protected MessageDigest(String algorithm) {
this.algorithm = algorithm;
@@ -73,7 +66,6 @@
* if the specified algorithm is not available
* @throws NullPointerException
* if {@code algorithm} is {@code null}
- * @since Android 1.0
*/
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -88,11 +80,9 @@
result.algorithm = algorithm;
result.provider = engine.provider;
return result;
- } else {
- result = new MessageDigestImpl((MessageDigestSpi) engine.spi,
- engine.provider, algorithm);
- return result;
}
+ return new MessageDigestImpl((MessageDigestSpi) engine.spi,
+ engine.provider, algorithm);
}
}
@@ -112,16 +102,17 @@
* if the specified provider is not available
* @throws NullPointerException
* if {@code algorithm} is {@code null}
- * @since Android 1.0
*/
public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
if ((provider == null) || (provider.length() == 0)) {
- throw new IllegalArgumentException(Messages.getString("security.02")); //$NON-NLS-1$
+ throw new IllegalArgumentException(Messages
+ .getString("security.02")); //$NON-NLS-1$
}
Provider p = Security.getProvider(provider);
if (p == null) {
- throw new NoSuchProviderException(Messages.getString("security.03", provider)); //$NON-NLS-1$
+ throw new NoSuchProviderException(Messages.getString(
+ "security.03", provider)); //$NON-NLS-1$
}
return getInstance(algorithm, p);
}
@@ -140,12 +131,12 @@
* if the specified algorithm is not available
* @throws NullPointerException
* if {@code algorithm} is {@code null}
- * @since Android 1.0
*/
public static MessageDigest getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
if (provider == null) {
- throw new IllegalArgumentException(Messages.getString("security.04")); //$NON-NLS-1$
+ throw new IllegalArgumentException(Messages
+ .getString("security.04")); //$NON-NLS-1$
}
if (algorithm == null) {
throw new NullPointerException(Messages.getString("security.01")); //$NON-NLS-1$
@@ -158,19 +149,16 @@
result.algorithm = algorithm;
result.provider = provider;
return result;
- } else {
- result = new MessageDigestImpl((MessageDigestSpi) engine.spi,
- provider, algorithm);
- return result;
}
+ result = new MessageDigestImpl((MessageDigestSpi) engine.spi,
+ provider, algorithm);
+ return result;
}
}
/**
* Puts this {@code MessageDigest} back in an initial state, such that it is
* ready to compute a one way hash value.
- *
- * @since Android 1.0
*/
public void reset() {
engineReset();
@@ -200,11 +188,10 @@
* @throws IllegalArgumentException
* if {@code offset} or {@code len} are not valid in respect to
* {@code input}
- * @since Android 1.0
*/
public void update(byte[] input, int offset, int len) {
if (input == null ||
- // offset < 0 || len < 0 ||
+ // offset < 0 || len < 0 ||
// checks for negative values are commented out intentionally
// see HARMONY-1120 for details
(long) offset + (long) len > input.length) {
@@ -221,7 +208,6 @@
* the {@code byte} array
* @throws NullPointerException
* if {@code input} is {@code null}
- * @since Android 1.0
*/
public void update(byte[] input) {
if (input == null) {
@@ -259,11 +245,10 @@
* if {@code offset} or {@code len} are not valid in respect to
* {@code buf}
* @see #reset()
- * @since Android 1.0
*/
public int digest(byte[] buf, int offset, int len) throws DigestException {
if (buf == null ||
- // offset < 0 || len < 0 ||
+ // offset < 0 || len < 0 ||
// checks for negative values are commented out intentionally
// see HARMONY-1148 for details
(long) offset + (long) len > buf.length) {
@@ -282,7 +267,6 @@
* the {@code byte} array
* @return the computed one way hash value
* @see #reset()
- * @since Android 1.0
*/
public byte[] digest(byte[] input) {
update(input);
@@ -294,8 +278,8 @@
* {@code MessageDigest} including the name of its algorithm.
*
* @return a printable representation for this {@code MessageDigest}
- * @since Android 1.0
*/
+ @Override
public String toString() {
return "MESSAGE DIGEST " + algorithm; //$NON-NLS-1$
}
@@ -309,7 +293,6 @@
* @param digestb
* the second digest to be compared
* @return {@code true} if the two hashes are equal, {@code false} otherwise
- * @since Android 1.0
*/
public static boolean isEqual(byte[] digesta, byte[] digestb) {
if (digesta.length != digestb.length) {
@@ -327,7 +310,6 @@
* Returns the name of the algorithm of this {@code MessageDigest}.
*
* @return the name of the algorithm of this {@code MessageDigest}
- * @since Android 1.0
*/
public final String getAlgorithm() {
return algorithm;
@@ -337,7 +319,6 @@
* Returns the provider associated with this {@code MessageDigest}.
*
* @return the provider associated with this {@code MessageDigest}
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -349,7 +330,6 @@
* {@code 0} is returned.
*
* @return the digest length in bytes, or {@code 0}
- * @since Android 1.0
*/
public final int getDigestLength() {
int l = engineGetDigestLength();
@@ -367,12 +347,12 @@
}
}
+ @Override
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
- } else {
- throw new CloneNotSupportedException();
}
+ throw new CloneNotSupportedException();
}
/**
@@ -380,7 +360,6 @@
*
* @param input
* the {@code ByteBuffer}
- * @since Android 1.0
*/
public final void update(ByteBuffer input) {
engineUpdate(input);
@@ -392,7 +371,7 @@
*
*/
private static class MessageDigestImpl extends MessageDigest {
-
+
// MessageDigestSpi implementation
private MessageDigestSpi spiImpl;
@@ -405,38 +384,44 @@
}
// engineReset() implementation
+ @Override
protected void engineReset() {
spiImpl.engineReset();
}
// engineDigest() implementation
+ @Override
protected byte[] engineDigest() {
return spiImpl.engineDigest();
}
// engineGetDigestLength() implementation
+ @Override
protected int engineGetDigestLength() {
return spiImpl.engineGetDigestLength();
}
// engineUpdate() implementation
+ @Override
protected void engineUpdate(byte arg0) {
spiImpl.engineUpdate(arg0);
}
// engineUpdate() implementation
+ @Override
protected void engineUpdate(byte[] arg0, int arg1, int arg2) {
spiImpl.engineUpdate(arg0, arg1, arg2);
}
// Returns a clone if the spiImpl is cloneable
+ @Override
public Object clone() throws CloneNotSupportedException {
if (spiImpl instanceof Cloneable) {
MessageDigestSpi spi = (MessageDigestSpi) spiImpl.clone();
return new MessageDigestImpl(spi, getProvider(), getAlgorithm());
- } else {
- throw new CloneNotSupportedException();
}
+
+ throw new CloneNotSupportedException();
}
}
}
diff --git a/security/src/main/java/java/security/MessageDigestSpi.java b/security/src/main/java/java/security/MessageDigestSpi.java
index ae5ed32..52ad3cd 100644
--- a/security/src/main/java/java/security/MessageDigestSpi.java
+++ b/security/src/main/java/java/security/MessageDigestSpi.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.nio.ByteBuffer;
@@ -33,7 +28,6 @@
* a fingerprint for a stream of bytes.
*
* @see MessageDigest
- * @since Android 1.0
*/
public abstract class MessageDigestSpi {
@@ -42,7 +36,6 @@
* implement this function {@code 0} is returned.
*
* @return the digest length in bytes, or {@code 0}.
- * @since Android 1.0
*/
protected int engineGetDigestLength() {
return 0;
@@ -54,10 +47,9 @@
* @param input
* the {@code byte} to update this {@code MessageDigestSpi} with.
* @see #engineReset()
- * @since Android 1.0
*/
protected abstract void engineUpdate(byte input);
-
+
/**
* Updates this {@code MessageDigestSpi} using the given {@code byte[]}.
*
@@ -70,7 +62,6 @@
* @throws IllegalArgumentException
* if {@code offset} or {@code len} are not valid in respect to
* {@code input}.
- * @since Android 1.0
*/
protected abstract void engineUpdate(byte[] input, int offset, int len);
@@ -79,7 +70,6 @@
*
* @param input
* the {@code ByteBuffer}.
- * @since Android 1.0
*/
protected void engineUpdate(ByteBuffer input) {
if (!input.hasRemaining()) {
@@ -107,7 +97,6 @@
*
* @return the computed one way hash value.
* @see #engineReset()
- * @since Android 1.0
*/
protected abstract byte[] engineDigest();
@@ -129,7 +118,6 @@
* if {@code offset} or {@code len} are not valid in respect to
* {@code buf}.
* @see #engineReset()
- * @since Android 1.0
*/
protected int engineDigest(byte[] buf, int offset, int len)
throws DigestException {
@@ -156,11 +144,10 @@
/**
* Puts this {@code MessageDigestSpi} back in an initial state, such that it
* is ready to compute a one way hash value.
- *
- * @since Android 1.0
*/
protected abstract void engineReset();
+ @Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
diff --git a/security/src/main/java/java/security/NoSuchAlgorithmException.java b/security/src/main/java/java/security/NoSuchAlgorithmException.java
index 3324076..8ef2e3f 100644
--- a/security/src/main/java/java/security/NoSuchAlgorithmException.java
+++ b/security/src/main/java/java/security/NoSuchAlgorithmException.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code NoSuchAlgorithmException} indicates that a requested algorithm could
* not be found.
- *
- * @since Android 1.0
*/
public class NoSuchAlgorithmException extends GeneralSecurityException {
@@ -35,10 +28,9 @@
/**
* Constructs a new instance of {@code NoSuchAlgorithmException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public NoSuchAlgorithmException(String msg) {
super(msg);
@@ -46,8 +38,6 @@
/**
* Constructs a new instance of {@code NoSuchAlgorithmException}.
- *
- * @since Android 1.0
*/
public NoSuchAlgorithmException() {
}
@@ -55,12 +45,11 @@
/**
* Constructs a new instance of {@code NoSuchAlgorithmException} with the
* given message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public NoSuchAlgorithmException(String message, Throwable cause) {
super(message, cause);
@@ -69,10 +58,9 @@
/**
* Constructs a new instance of {@code NoSuchAlgorithmException} with the
* cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public NoSuchAlgorithmException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/NoSuchProviderException.java b/security/src/main/java/java/security/NoSuchProviderException.java
index f016ce6..57cda40 100644
--- a/security/src/main/java/java/security/NoSuchProviderException.java
+++ b/security/src/main/java/java/security/NoSuchProviderException.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code NoSuchProviderException} indicates that a requested security provider
* could not be found.
- *
- * @since Android 1.0
*/
public class NoSuchProviderException extends GeneralSecurityException {
@@ -35,10 +28,9 @@
/**
* Constructs a new instance of {@code NoSuchProviderException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public NoSuchProviderException(String msg) {
super(msg);
@@ -46,8 +38,6 @@
/**
* Constructs a new instance of {@code NoSuchProviderException}.
- *
- * @since Android 1.0
*/
public NoSuchProviderException() {
}
diff --git a/security/src/main/java/java/security/Permission.java b/security/src/main/java/java/security/Permission.java
index 93e769c..26bdfcd 100644
--- a/security/src/main/java/java/security/Permission.java
+++ b/security/src/main/java/java/security/Permission.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.io.Serializable;
@@ -29,8 +24,6 @@
* participate in the access control security framework around
* {@link AccessController} and {@link AccessControlContext}. A permission
* constitutes of a name and associated actions.
- *
- * @since Android 1.0
*/
public abstract class Permission implements Guard, Serializable {
@@ -45,46 +38,44 @@
* <p>
* The {@link #implies(Permission)} method should be used for making access
* control checks.
- * </p>
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* Permission}.
* @return {@code true} if the specified object is equal to this {@code
* Permission}, otherwise {@code false}.
- * @since Android 1.0
*/
+ @Override
public abstract boolean equals(Object obj);
/**
* Returns the hash code value for this {@code Permission}. Returns the same
* hash code for {@code Permission}s that are equal to each other as
* required by the general contract of {@link Object#hashCode}.
- *
+ *
* @return the hash code value for this {@code Permission}.
* @see Object#equals(Object)
* @see Permission#equals(Object)
- * @since Android 1.0
*/
+ @Override
public abstract int hashCode();
/**
* Returns a comma separated string identifying the actions associated with
* this permission. The returned actions are in canonical form. For example:
- *
+ *
* <pre>
- * sp0 = new SocketPermission("www.google.com", "connect,resolve")
- * sp1 = new SocketPermission("www.google.com", "resolve,connect")
+ * sp0 = new SocketPermission("www.example.com", "connect,resolve")
+ * sp1 = new SocketPermission("www.example.com", "resolve,connect")
* sp0.getActions().equals(sp1.getActions()) //yields true
* </pre>
- *
+ *
* Both permissions return "connect,resolve" (in that order) if {@code
* #getActions()} is invoked. Returns an empty String, if no actions are
* associated with this permission.
- *
+ *
* @return the actions associated with this permission or an empty string if
* no actions are associated with this permission.
- * @since Android 1.0
*/
public abstract String getActions();
@@ -92,21 +83,19 @@
* Indicates whether the specified permission is implied by this permission.
* The {@link AccessController} uses this method to check whether permission
* protected access is allowed with the present policy.
- *
+ *
* @param permission
* the permission to check against this permission.
* @return {@code true} if the specified permission is implied by this
* permission, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean implies(Permission permission);
/**
* Constructs a new instance of {@code Permission} with its name.
- *
+ *
* @param name
* the name of the permission.
- * @since Android 1.0
*/
public Permission(String name) {
this.name = name;
@@ -114,9 +103,8 @@
/**
* Returns the name of this permission.
- *
+ *
* @return the name of this permission.
- * @since Android 1.0
*/
public final String getName() {
return name;
@@ -126,7 +114,7 @@
* Invokes {@link SecurityManager#checkPermission(Permission)} with this
* permission as its argument. This method implements the {@link Guard}
* interface.
- *
+ *
* @param obj
* as specified in {@link Guard#checkGuard(Object)} but ignored
* in this implementation.
@@ -134,7 +122,6 @@
* if this permission is not granted.
* @see Guard
* @see SecurityManager#checkPermission(Permission)
- * @since Android 1.0
*/
public void checkGuard(Object obj) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
@@ -150,11 +137,9 @@
* <p>
* Subclasses may override this method to return an appropriate collection
* for the specific permissions they implement.
- * </p>
- *
+ *
* @return an empty {@link PermissionCollection} or {@code null} if any
* permission collection can be used.
- * @since Android 1.0
*/
public PermissionCollection newPermissionCollection() {
return null;
@@ -163,10 +148,10 @@
/**
* Returns a string containing a concise, human-readable description of the
* this {@code Permission} including its name and its actions.
- *
+ *
* @return a printable representation for this {@code Permission}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
String actions = getActions();
actions = (actions == null || actions.length() == 0) ? "" : " " //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/security/src/main/java/java/security/PermissionCollection.java b/security/src/main/java/java/security/PermissionCollection.java
index 2502123..56b6cd0 100644
--- a/security/src/main/java/java/security/PermissionCollection.java
+++ b/security/src/main/java/java/security/PermissionCollection.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.io.Serializable;
@@ -37,12 +32,8 @@
* method returns {@code null}, then a {@code PermissionCollection} of any type
* can be used. If a collection is returned, it must be used for holding several
* permissions of the particular type.
- * </p>
* <p>
* Subclasses must be implemented thread save.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class PermissionCollection implements Serializable {
@@ -57,7 +48,6 @@
* the {@code Permission} to add.
* @throws IllegalStateException
* if the collection is read only.
- * @since Android 1.0
*/
public abstract void add(Permission permission);
@@ -66,7 +56,6 @@
* {@code PermissionCollection}.
*
* @return an enumeration over all {@link Permission}s.
- * @since Android 1.0
*/
public abstract Enumeration<Permission> elements();
@@ -78,7 +67,6 @@
* the permission to check.
* @return {@code true} if the given permission is implied by the
* permissions in this collection, {@code false} otherwise.
- * @since Android 1.0
*/
public abstract boolean implies(Permission permission);
@@ -88,7 +76,6 @@
*
* @return {@code true} if the receiver is read only, {@code false} if new
* elements can still be added to this {@code PermissionCollection}.
- * @since Android 1.0
*/
public boolean isReadOnly() {
return readOnly;
@@ -97,8 +84,6 @@
/**
* Marks this {@code PermissionCollection} as read only, so that no new
* permissions can be added to it.
- *
- * @since Android 1.0
*/
public void setReadOnly() {
readOnly = true;
@@ -109,11 +94,11 @@
* {@code PermissionCollection}.
*
* @return a printable representation for this {@code PermissionCollection}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- List elist = new ArrayList(100);
- Enumeration elenum = elements();
+ List<String> elist = new ArrayList<String>(100);
+ Enumeration<Permission> elenum = elements();
String superStr = super.toString();
int totalLength = superStr.length() + 5;
if (elenum != null) {
@@ -125,12 +110,11 @@
}
int esize = elist.size();
totalLength += esize * 4;
- //FIXME StringBuffer --> StringBuilder
- StringBuffer result = new StringBuffer(totalLength).append(superStr)
+ StringBuilder result = new StringBuilder(totalLength).append(superStr)
.append(" ("); //$NON-NLS-1$
for (int i = 0; i < esize; i++) {
- result.append("\n ").append(elist.get(i).toString()); //$NON-NLS-1$
+ result.append("\n ").append(elist.get(i).toString()); //$NON-NLS-1$
}
- return result.append("\n)").toString(); //$NON-NLS-1$
+ return result.append("\n)\n").toString(); //$NON-NLS-1$
}
}
diff --git a/security/src/main/java/java/security/Permissions.java b/security/src/main/java/java/security/Permissions.java
index b9b13c6..e8d3375 100644
--- a/security/src/main/java/java/security/Permissions.java
+++ b/security/src/main/java/java/security/Permissions.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
@@ -44,8 +39,6 @@
* {@link Permission#newPermissionCollection()}. For permissions which do not
* provide a dedicated {@code PermissionCollection}, a default permission
* collection, based on a hash table, will be used.
- *
- * @since Android 1.0
*/
public final class Permissions extends PermissionCollection implements
Serializable {
@@ -65,7 +58,7 @@
* Adds the given {@code Permission} to this heterogeneous {@code
* PermissionCollection}. The {@code permission} is stored in its
* appropriate {@code PermissionCollection}.
- *
+ *
* @param permission
* the {@code Permission} to be added.
* @throws SecurityException
@@ -73,7 +66,6 @@
* {@code true}.
* @throws NullPointerException
* if {@code permission} is {@code null}.
- * @since Android 1.0
*/
public void add(Permission permission) {
if (isReadOnly()) {
@@ -223,9 +215,10 @@
Map perms = (Map)fields.get("perms", null); //$NON-NLS-1$
klasses = new HashMap();
synchronized (klasses) {
- for (Iterator iter = perms.keySet().iterator(); iter.hasNext();) {
- Class key = (Class)iter.next();
- PermissionCollection pc = (PermissionCollection)perms.get(key);
+ for (Iterator iter = perms.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ Class key = (Class) entry.getKey();
+ PermissionCollection pc = (PermissionCollection) entry.getValue();
if (key != pc.elements().nextElement().getClass()) {
throw new InvalidObjectException(Messages.getString("security.22")); //$NON-NLS-1$
}
diff --git a/security/src/main/java/java/security/PermissionsHash.java b/security/src/main/java/java/security/PermissionsHash.java
index 69d2b07..4c9e0c9 100644
--- a/security/src/main/java/java/security/PermissionsHash.java
+++ b/security/src/main/java/java/security/PermissionsHash.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.util.Enumeration;
@@ -30,28 +25,21 @@
/**
* A default {@code PermissionCollection} implementation that uses a hashtable.
* Each hashtable entry stores a Permission object as both the key and the
- * value. <br>
+ * value.
+ * <p>
* This {@code PermissionCollection} is intended for storing "neutral"
- * permissions which do not require special collection. </br>
- *
- * @since Android 1.0
+ * permissions which do not require special collection.
*/
final class PermissionsHash extends PermissionCollection {
- /**
- * @com.intel.drl.spec_ref
- */
private static final long serialVersionUID = -8491988220802933440L;
- /**
- * @com.intel.drl.spec_ref
- */
private final Hashtable perms = new Hashtable();
/**
* Adds the argument to the collection.
- *
+ *
* @param permission
* the permission to add to the collection.
*/
@@ -61,8 +49,7 @@
/**
* Returns an enumeration of the permissions in the receiver.
- *
- *
+ *
* @return Enumeration the permissions in the receiver.
*/
public Enumeration elements() {
@@ -72,8 +59,7 @@
/**
* Indicates whether the argument permission is implied by the permissions
* contained in the receiver.
- *
- *
+ *
* @return boolean <code>true</code> if the argument permission is implied
* by the permissions in the receiver, and <code>false</code> if
* it is not.
diff --git a/security/src/main/java/java/security/Policy.java b/security/src/main/java/java/security/Policy.java
index 21b13b0..d5719a3 100644
--- a/security/src/main/java/java/security/Policy.java
+++ b/security/src/main/java/java/security/Policy.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.util.Enumeration;
@@ -36,12 +31,8 @@
* The system policy can be changed by setting the {@code 'policy.provider'}
* property in the file named {@code JAVA_HOME/lib/security/java.security} to
* the fully qualified class name of the desired {@code Policy}.
- * </p>
* <p>
* Only one instance of a {@code Policy} is active at any time.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class Policy {
@@ -68,20 +59,16 @@
* domain (i.e. system classes). System classes are always given
* full permissions (i.e. AllPermission). This can not be changed by
* installing a new policy.
- * </p>
- *
+ *
* @param cs
* the {@code CodeSource} to compute the permissions for.
* @return the permissions that are granted to the specified {@code
* CodeSource}.
- * @since Android 1.0
*/
public abstract PermissionCollection getPermissions(CodeSource cs);
/**
* Reloads the policy configuration for this {@code Policy} instance.
- *
- * @since Android 1.0
*/
public abstract void refresh();
@@ -94,13 +81,11 @@
* system domain (i.e. system classes). System classes are always
* given full permissions (i.e. AllPermission). This can not be changed by
* installing a new policy.
- * </p>
- *
+ *
* @param domain
* the {@code ProtectionDomain} to compute the permissions for.
* @return the permissions that are granted to the specified {@code
* CodeSource}.
- * @since Android 1.0
*/
public PermissionCollection getPermissions(ProtectionDomain domain) {
if (domain != null) {
@@ -112,7 +97,7 @@
/**
* Indicates whether the specified {@code Permission} is implied by the
* {@code PermissionCollection} of the specified {@code ProtectionDomain}.
- *
+ *
* @param domain
* the {@code ProtectionDomain} for which the permission should
* be granted.
@@ -121,7 +106,6 @@
* verified.
* @return {@code true} if the {@code Permission} is implied by the {@code
* ProtectionDomain}, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean implies(ProtectionDomain domain, Permission permission) {
if (domain != null) {
@@ -130,8 +114,8 @@
if (total == null) {
total = inherent;
} else if (inherent != null) {
- for (Enumeration en = inherent.elements(); en.hasMoreElements();) {
- total.add((Permission)en.nextElement());
+ for (Enumeration<Permission> en = inherent.elements(); en.hasMoreElements();) {
+ total.add(en.nextElement());
}
}
if (total != null && total.implies(permission)) {
@@ -149,13 +133,11 @@
* If a {@code SecurityManager} is installed, code calling this method needs
* the {@code SecurityPermission} {@code getPolicy} to be granted, otherwise
* a {@code SecurityException} will be thrown.
- * </p>
- *
+ *
* @return the current system security policy.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public static Policy getPolicy() {
SecurityManager sm = System.getSecurityManager();
@@ -170,7 +152,7 @@
// In case of any error, including undefined provider name,
// returns new instance of org.apache.harmony.security.FilePolicy provider.
private static Policy getDefaultProvider() {
- final String defaultClass = (String) AccessController
+ final String defaultClass = AccessController
.doPrivileged(new PolicyUtils.SecurityPropertyAccessor(
POLICY_PROVIDER));
if (defaultClass == null) {
@@ -235,14 +217,12 @@
* If a {@code SecurityManager} is installed, code calling this method needs
* the {@code SecurityPermission} {@code setPolicy} to be granted, otherwise
* a {@code SecurityException} will be thrown.
- * </p>
- *
+ *
* @param policy
* the {@code Policy} to set.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public static void setPolicy(Policy policy) {
SecurityManager sm = System.getSecurityManager();
diff --git a/security/src/main/java/java/security/Principal.java b/security/src/main/java/java/security/Principal.java
index 0716681..f86bc87 100644
--- a/security/src/main/java/java/security/Principal.java
+++ b/security/src/main/java/java/security/Principal.java
@@ -15,40 +15,31 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code Principal}s are objects which have identities. These can be
* individuals, groups, corporations, unique program executions, etc.
- *
- * @since Android 1.0
*/
public interface Principal {
/**
* Compares the specified object with this {@code Principal} for equality
* and returns {@code true} if the specified object is equal, {@code false}
* otherwise.
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* Principal}.
* @return {@code true} if the specified object is equal to this {@code
* Principal}, otherwise {@code false}.
- * @since Android 1.0
*/
public boolean equals( Object obj );
/**
* Returns the name of this {@code Principal}.
- *
+ *
* @return the name of this {@code Principal}.
- * @since Android 1.0
*/
public String getName();
@@ -60,16 +51,14 @@
* @return the hash code value for this {@code Principal}.
* @see Object#equals(Object)
* @see Principal#equals(Object)
- * @since Android 1.0
*/
public int hashCode();
-
- /**
+
+ /**
* Returns a string containing a concise, human-readable description of
* this {@code Principal}.
*
* @return a printable representation for this {@code Principal}.
- * @since Android 1.0
*/
public String toString();
}
diff --git a/security/src/main/java/java/security/PrivateKey.java b/security/src/main/java/java/security/PrivateKey.java
index 8513b75..246f286 100644
--- a/security/src/main/java/java/security/PrivateKey.java
+++ b/security/src/main/java/java/security/PrivateKey.java
@@ -15,25 +15,17 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code PrivateKey} is the common interface for private keys.
*
* @see PublicKey
- * @since Android 1.0
*/
public interface PrivateKey extends Key {
-
+
/**
* The {@code serialVersionUID} to be compatible with JDK1.1.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = 6034044314589513430L;
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/PrivilegedAction.java b/security/src/main/java/java/security/PrivilegedAction.java
index 5912cdc..1dbbe65 100644
--- a/security/src/main/java/java/security/PrivilegedAction.java
+++ b/security/src/main/java/java/security/PrivilegedAction.java
@@ -15,31 +15,23 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code PrivilegedAction} represents an action that can be executed privileged
* regarding access control. Instances of {@code PrivilegedAction} can be
* executed on {@code AccessController.doPrivileged()}.
- *
+ *
* @see AccessController
* @see AccessController#doPrivileged(PrivilegedAction)
* @see AccessController#doPrivileged(PrivilegedAction, AccessControlContext)
* @see PrivilegedExceptionAction
- * @since Android 1.0
*/
public interface PrivilegedAction<T> {
-
/**
* Returns the result of running the action.
- *
+ *
* @return the result of running the action.
- * @since Android 1.0
*/
public T run();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/PrivilegedActionException.java b/security/src/main/java/java/security/PrivilegedActionException.java
index eaca2b2..a1f5b15 100644
--- a/security/src/main/java/java/security/PrivilegedActionException.java
+++ b/security/src/main/java/java/security/PrivilegedActionException.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
/**
@@ -33,13 +28,11 @@
* {@code AccessController#doPrivileged(PrivilegedExceptionAction,
* AccessControlContext)} </br>
* </ul>
- * </p>
- *
+ *
* @see PrivilegedExceptionAction
* @see AccessController#doPrivileged(PrivilegedExceptionAction)
* @see AccessController#doPrivileged(PrivilegedExceptionAction,
* AccessControlContext)
- * @since Android 1.0
*/
public class PrivilegedActionException extends Exception {
@@ -50,10 +43,9 @@
/**
* Constructs a new instance of {@code PrivilegedActionException} with the
* cause.
- *
+ *
* @param ex
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public PrivilegedActionException(Exception ex) {
super(ex);
@@ -63,10 +55,9 @@
/**
* Returns the exception that was thrown by a
* {@code PrivilegedExceptionAction}.
- *
+ *
* @return the exception that was thrown by a
* {@code PrivilegedExceptionAction}.
- * @since Android 1.0
*/
public Exception getException() {
return exception; // return ( getCause() instanceof Exception ) ?
@@ -76,11 +67,11 @@
/**
* Returns the exception that was thrown by a
* {@code PrivilegedExceptionAction}.
- *
+ *
* @return the exception that was thrown by a
* {@code PrivilegedExceptionAction}.
- * @since Android 1.0
*/
+ @Override
public Throwable getCause() {
return exception;
}
@@ -88,11 +79,11 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code PrivilegedActionException}.
- *
+ *
* @return a printable representation for this {@code
* PrivilegedActionException}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
String s = getClass().getName();
return exception == null ? s : s + ": " + exception; //$NON-NLS-1$
diff --git a/security/src/main/java/java/security/PrivilegedExceptionAction.java b/security/src/main/java/java/security/PrivilegedExceptionAction.java
index dd3ae8d..bc072d5 100644
--- a/security/src/main/java/java/security/PrivilegedExceptionAction.java
+++ b/security/src/main/java/java/security/PrivilegedExceptionAction.java
@@ -15,34 +15,26 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code PrivilegedAction} represents an action, that can be executed
* privileged regarding access control. Instances of {@code PrivilegedAction}
* can be executed invoking {@code AccessController.doPrivileged()}.
- *
+ *
* @see AccessController
* @see AccessController#doPrivileged(PrivilegedExceptionAction)
* @see AccessController#doPrivileged(PrivilegedExceptionAction,
* AccessControlContext)
* @see PrivilegedAction
- * @since Android 1.0
*/
public interface PrivilegedExceptionAction<T> {
-
/**
* Returns the result of running the action.
- *
+ *
* @return the result of running the action
* @throws Exception
* if an exception occurred.
- * @since Android 1.0
*/
T run() throws Exception;
}
diff --git a/security/src/main/java/java/security/ProtectionDomain.java b/security/src/main/java/java/security/ProtectionDomain.java
index d41f4a8..1e85c4a 100644
--- a/security/src/main/java/java/security/ProtectionDomain.java
+++ b/security/src/main/java/java/security/ProtectionDomain.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
/**
@@ -30,9 +25,6 @@
* <p>
* A class belongs to exactly one protection domain and the protection domain
* can not be changed during the lifetime of the class.
- * </p>
- *
- * @since Android 1.0
*/
public class ProtectionDomain {
@@ -60,17 +52,13 @@
* collection is made immutable by calling
* {@link PermissionCollection#setReadOnly()} and it is considered as
* granted statically to this {@code ProtectionDomain}.
- * </p>
* <p>
* The policy will not be consulted by access checks against this {@code
* ProtectionDomain}.
- * </p>
* <p>
- * If {@code permissions} is {@code null}, the method
- * {@link ProtectionDomain#implies(Permission)} always returns {@code false}
- * .
- * </p>
- *
+ * If {@code permissions} is {@code null}, the method {@link
+ * ProtectionDomain#implies(Permission)} always returns {@code false}.
+ *
* @param cs
* the code source associated with this domain, maybe {@code
* null}.
@@ -78,7 +66,6 @@
* the {@code PermissionCollection} containing all permissions to
* be statically granted to this {@code ProtectionDomain}, maybe
* {@code null}.
- * @since Android 1.0
*/
public ProtectionDomain(CodeSource cs, PermissionCollection permissions) {
this.codeSource = cs;
@@ -91,7 +78,6 @@
//dynamicPerms = false;
}
-
/**
* Constructs a new instance of {@code ProtectionDomain} with the specified
* code source, the permissions, the class loader and the principals.
@@ -102,12 +88,10 @@
* permissions} collection is made immutable by calling
* {@link PermissionCollection#setReadOnly()}. If access checks are
* performed, the policy and the provided permission collection are checked.
- * </p>
* <p>
* External modifications of the provided {@code principals} array has no
* impact on this {@code ProtectionDomain}.
- * </p>
- *
+ *
* @param cs
* the code source associated with this domain, maybe {@code
* null}.
@@ -118,9 +102,8 @@
* the class loader associated with this domain, maybe {@code
* null}.
* @param principals
- * the principals associated with this domain, maybe {@code null}
- * .
- * @since Android 1.0
+ * the principals associated with this domain, maybe {@code
+ * null}.
*/
public ProtectionDomain(CodeSource cs, PermissionCollection permissions,
ClassLoader cl, Principal[] principals) {
@@ -141,10 +124,9 @@
/**
* Returns the {@code ClassLoader} associated with this {@code
* ProtectionDomain}.
- *
+ *
* @return the {@code ClassLoader} associated with this {@code
* ProtectionDomain}, maybe {@code null}.
- * @since Android 1.0
*/
public final ClassLoader getClassLoader() {
return classLoader;
@@ -152,10 +134,9 @@
/**
* Returns the {@code CodeSource} of this {@code ProtectionDomain}.
- *
+ *
* @return the {@code CodeSource} of this {@code ProtectionDomain}, maybe
* {@code null}.
- * @since Android 1.0
*/
public final CodeSource getCodeSource() {
return codeSource;
@@ -164,10 +145,9 @@
/**
* Returns the static permissions that are granted to this {@code
* ProtectionDomain}.
- *
+ *
* @return the static permissions that are granted to this {@code
* ProtectionDomain}, maybe {@code null}.
- * @since Android 1.0
*/
public final PermissionCollection getPermissions() {
return permissions;
@@ -177,9 +157,8 @@
* Returns the principals associated with this {@code ProtectionDomain}.
* Modifications of the returned {@code Principal} array has no impact on
* this {@code ProtectionDomain}.
- *
+ *
* @return the principals associated with this {@code ProtectionDomain}.
- * @since Android 1.0
*/
public final Principal[] getPrincipals() {
if( principals == null ) {
@@ -199,19 +178,16 @@
* specified permission is only checked against the permission collection
* provided in the constructor. If {@code null} was provided, {@code false}
* is returned.
- * </p>
* <p>
* If this {@code ProtectionDomain} was constructed with
* {@link #ProtectionDomain(CodeSource, PermissionCollection, ClassLoader, Principal[])}
* , the specified permission is checked against the policy and the
* permission collection provided in the constructor.
- * </p>
- *
+ *
* @param permission
* the permission to check against the domain.
* @return {@code true} if the specified {@code permission} is implied by
* this {@code ProtectionDomain}, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean implies(Permission permission) {
// First, test with the Policy, as the default Policy.implies()
@@ -232,13 +208,12 @@
/**
* Returns a string containing a concise, human-readable description of the
* this {@code ProtectionDomain}.
- *
+ *
* @return a printable representation for this {@code ProtectionDomain}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- //FIXME: 1.5 use StreamBuilder here
- StringBuffer buf = new StringBuffer(200);
+ StringBuilder buf = new StringBuilder(200);
buf.append("ProtectionDomain\n"); //$NON-NLS-1$
buf.append("CodeSource=").append( //$NON-NLS-1$
codeSource == null ? "<null>" : codeSource.toString()).append( //$NON-NLS-1$
diff --git a/security/src/main/java/java/security/Provider.java b/security/src/main/java/java/security/Provider.java
index 491470f..cf9c94d 100644
--- a/security/src/main/java/java/security/Provider.java
+++ b/security/src/main/java/java/security/Provider.java
@@ -15,15 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
import java.io.InputStream;
+import java.io.NotActiveException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -37,14 +33,13 @@
import java.util.Set;
import org.apache.harmony.luni.util.TwoKeyHashMap;
+import org.apache.harmony.security.Util;
import org.apache.harmony.security.fortress.Services;
import org.apache.harmony.security.internal.nls.Messages;
/**
* {@code Provider} is the abstract superclass for all security providers in the
* Java security infrastructure.
- *
- * @since Android 1.0
*/
public abstract class Provider extends Properties {
private static final long serialVersionUID = -4298000515446427739L;
@@ -99,14 +94,13 @@
/**
* Constructs a new instance of {@code Provider} with its name, version and
* description.
- *
+ *
* @param name
* the name of the provider.
* @param version
* the version of the provider.
* @param info
* a description of the provider.
- * @since Android 1.0
*/
protected Provider(String name, double version, String info) {
this.name = name;
@@ -118,9 +112,8 @@
/**
* Returns the name of this provider.
- *
+ *
* @return the name of this provider.
- * @since Android 1.0
*/
public String getName() {
return name;
@@ -128,9 +121,8 @@
/**
* Returns the version number for the services being provided.
- *
+ *
* @return the version number for the services being provided.
- * @since Android 1.0
*/
public double getVersion() {
return version;
@@ -138,9 +130,8 @@
/**
* Returns a description of the services being provided.
- *
+ *
* @return a description of the services being provided.
- * @since Android 1.0
*/
public String getInfo() {
return info;
@@ -151,12 +142,10 @@
* this {@code Provider} including its name and its version.
*
* @return a printable representation for this {@code Provider}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- // BEGIN android-changed
return name + " version " + version; //$NON-NLS-1$
- // END android-changed
}
/**
@@ -167,13 +156,12 @@
* the {@code SecurityPermission} {@code clearProviderProperties.NAME}
* (where NAME is the provider name) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- * </p>
- *
+ *
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
+ @Override
public synchronized void clear() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@@ -203,6 +191,7 @@
servicesChanged();
}
+ @Override
public synchronized void load(InputStream inStream) throws IOException {
Properties tmp = new Properties();
tmp.load(inStream);
@@ -216,15 +205,14 @@
* the {@code SecurityPermission} {@code putProviderProperty.NAME} (where
* NAME is the provider name) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- * </p>
- *
+ *
* @param t
* the mappings to copy to this provider.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
+ @Override
public synchronized void putAll(Map<?,?> t) {
// Implementation note:
@@ -265,14 +253,17 @@
}
}
+ @Override
public synchronized Set<Map.Entry<Object,Object>> entrySet() {
return Collections.unmodifiableSet(super.entrySet());
}
+ @Override
public Set<Object> keySet() {
return Collections.unmodifiableSet(super.keySet());
}
+ @Override
public Collection<Object> values() {
return Collections.unmodifiableCollection(super.values());
}
@@ -285,8 +276,7 @@
* the {@code SecurityPermission} {@code putProviderProperty.NAME} (where
* NAME is the provider name) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- * </p>
- *
+ *
* @param key
* the name of the property.
* @param value
@@ -296,8 +286,8 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
+ @Override
public synchronized Object put(Object key, Object value) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@@ -329,8 +319,7 @@
* the {@code SecurityPermission} {@code removeProviderProperty.NAME} (where
* NAME is the provider name) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- * </p>
- *
+ *
* @param key
* the name of the property
* @return the value that was mapped to the specified {@code key} ,or
@@ -338,8 +327,8 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have the permission to invoke this method.
- * @since Android 1.0
*/
+ @Override
public synchronized Object remove(Object key) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@@ -365,9 +354,9 @@
}
/**
- * returns true if the provider implements the specified algorithm. Caller
+ * Returns true if this provider implements the given algorithm. Caller
* must specify the cryptographic service and specify constraints via the
- * attribute name the attribute value
+ * attribute name and value.
*
* @param serv
* Crypto service.
@@ -386,33 +375,32 @@
alg = getPropertyIgnoreCase("Alg.Alias." + servAlg); //$NON-NLS-1$
if (alg != null) {
servAlg = serv + "." + alg; //$NON-NLS-1$
- prop = getPropertyIgnoreCase(serv + "." + alg); //$NON-NLS-1$
+ prop = getPropertyIgnoreCase(servAlg);
}
}
if (prop != null) {
if (attribute == null) {
return true;
- } else {
- return checkAttribute(serv + "." + alg, attribute, val); //$NON-NLS-1$
}
+ return checkAttribute(servAlg, attribute, val);
}
return false;
}
- // returns true if the implementation meets the constraint expressed by the
- // specified attribute name/value pair.
+ // Returns true if this provider has the same value as is given for the
+ // given attribute
private boolean checkAttribute(String servAlg, String attribute, String val) {
String attributeValue = getPropertyIgnoreCase(servAlg + ' ' + attribute);
if (attributeValue != null) {
- if (attribute.equalsIgnoreCase("KeySize")) { //$NON-NLS-1$
+ if (Util.equalsIgnoreCase(attribute,"KeySize")) { //$NON-NLS-1$
// BEGIN android-changed
if (Integer.parseInt(attributeValue) >= Integer.parseInt(val)) {
return true;
}
// END android-changed
} else { // other attributes
- if (attributeValue.equalsIgnoreCase(val)) {
+ if (Util.equalsIgnoreCase(attributeValue, val)) {
return true;
}
}
@@ -469,14 +457,13 @@
* If two services match the requested type and algorithm, the one added
* with the {@link #putService(Service)} is returned (as opposed to the one
* added via {@link #put(Object, Object)}.
- *
+ *
* @param type
* the type of the service (for example {@code KeyPairGenerator})
* @param algorithm
* the algorithm name (case insensitive)
* @return the requested service, or {@code null} if no such implementation
* exists
- * @since Android 1.0
*/
public synchronized Provider.Service getService(String type,
String algorithm) {
@@ -485,11 +472,11 @@
}
if (type.equals(lastServiceName)
- && algorithm.equalsIgnoreCase(lastAlgorithm)) {
+ && Util.equalsIgnoreCase(algorithm, lastAlgorithm)) {
return returnedService;
}
- String alg = algorithm.toUpperCase();
+ String alg = Util.toUpperCase(algorithm);
Object o = null;
if (serviceTable != null) {
o = serviceTable.get(type, alg);
@@ -519,10 +506,9 @@
/**
* Returns an unmodifiable {@code Set} of all services registered by this
* provider.
- *
+ *
* @return an unmodifiable {@code Set} of all services registered by this
* provider
- * @since Android 1.0
*/
public synchronized Set<Provider.Service> getServices() {
updatePropertyServiceTable();
@@ -549,13 +535,12 @@
* the {@code SecurityPermission} {@code putProviderProperty.NAME} (where
* NAME is the provider name) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- *
+ *
* @param s
* the {@code Service} to register
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method
- * @since Android 1.0
*/
protected synchronized void putService(Provider.Service s) {
if (s == null) {
@@ -573,13 +558,13 @@
if (serviceTable == null) {
serviceTable = new TwoKeyHashMap<String, String, Service>(128);
}
- serviceTable.put(s.type, s.algorithm.toUpperCase(), s);
+ serviceTable.put(s.type, Util.toUpperCase(s.algorithm), s);
if (s.aliases != null) {
if (aliasTable == null) {
aliasTable = new TwoKeyHashMap<String, String, Service>(256);
}
for (Iterator<String> it = s.getAliases(); it.hasNext();) {
- aliasTable.put(s.type, (it.next()).toUpperCase(), s);
+ aliasTable.put(s.type, Util.toUpperCase(it.next()), s);
}
}
serviceInfoToProperties(s);
@@ -593,7 +578,7 @@
* the {@code SecurityPermission} {@code removeProviderProperty.NAME} (where
* NAME is the provider name) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- *
+ *
* @param s
* the {@code Service} to remove
* @throws SecurityException
@@ -601,7 +586,6 @@
* not have permission to invoke this method
* @throws NullPointerException
* if {@code s} is {@code null}
- * @since Android 1.0
*/
protected synchronized void removeService(Provider.Service s) {
if (s == null) {
@@ -613,11 +597,11 @@
}
servicesChanged();
if (serviceTable != null) {
- serviceTable.remove(s.type, s.algorithm.toUpperCase());
+ serviceTable.remove(s.type, Util.toUpperCase(s.algorithm));
}
if (aliasTable != null && s.aliases != null) {
for (Iterator<String> it = s.getAliases(); it.hasNext();) {
- aliasTable.remove(s.type, (it.next()).toUpperCase());
+ aliasTable.remove(s.type, Util.toUpperCase(it.next()));
}
}
serviceInfoFromProperties(s);
@@ -678,14 +662,14 @@
String algorithm = null;
String attribute = null;
int i;
- if (k.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<stanbdardName> //$NON-NLS-1$
+ if (k.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<standardName> //$NON-NLS-1$
String aliasName;
String service_alias = k.substring(10);
- i = service_alias.indexOf("."); //$NON-NLS-1$
+ i = service_alias.indexOf('.');
serviceName = service_alias.substring(0, i);
aliasName = service_alias.substring(i + 1);
if (propertyAliasTable != null) {
- propertyAliasTable.remove(serviceName, aliasName.toUpperCase());
+ propertyAliasTable.remove(serviceName, Util.toUpperCase(aliasName));
}
if (propertyServiceTable != null) {
for (Iterator<Service> it = propertyServiceTable.values().iterator(); it
@@ -699,22 +683,22 @@
}
return;
}
- int j = k.indexOf("."); //$NON-NLS-1$
+ int j = k.indexOf('.');
if (j == -1) { // unknown format
return;
}
- i = k.indexOf(" "); //$NON-NLS-1$
+ i = k.indexOf(' ');
if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
serviceName = k.substring(0, j);
algorithm = k.substring(j + 1);
if (propertyServiceTable != null) {
- Provider.Service ser = propertyServiceTable.remove(serviceName, algorithm.toUpperCase());
+ Provider.Service ser = propertyServiceTable.remove(serviceName, Util.toUpperCase(algorithm));
if (ser != null && propertyAliasTable != null
&& ser.aliases != null) {
for (Iterator<String> it = ser.aliases.iterator(); it.hasNext();) {
- propertyAliasTable.remove(serviceName, (it
- .next()).toUpperCase());
+ propertyAliasTable.remove(serviceName, Util.toUpperCase(it
+ .next()));
}
}
}
@@ -724,8 +708,7 @@
serviceName = k.substring(0, j);
algorithm = k.substring(j + 1, i);
if (propertyServiceTable != null) {
- Object o = propertyServiceTable.get(serviceName, algorithm
- .toUpperCase());
+ Object o = propertyServiceTable.get(serviceName, Util.toUpperCase(algorithm));
if (o != null) {
s = (Provider.Service) o;
s.attributes.remove(attribute);
@@ -759,14 +742,14 @@
continue;
}
int i;
- if (key.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<stanbdardName> //$NON-NLS-1$
+ if (key.startsWith("Alg.Alias.")) { // Alg.Alias.<crypto_service>.<aliasName>=<standardName> //$NON-NLS-1$
String aliasName;
String service_alias = key.substring(10);
- i = service_alias.indexOf("."); //$NON-NLS-1$
+ i = service_alias.indexOf('.');
serviceName = service_alias.substring(0, i);
aliasName = service_alias.substring(i + 1);
algorithm = value;
- String algUp = algorithm.toUpperCase();
+ String algUp = Util.toUpperCase(algorithm);
Object o = null;
if (propertyServiceTable == null) {
propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128);
@@ -782,7 +765,7 @@
propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256);
}
propertyAliasTable.put(serviceName,
- aliasName.toUpperCase(), s);
+ Util.toUpperCase(aliasName), s);
} else {
String className = (String) changedProperties
.get(serviceName + "." + algorithm); //$NON-NLS-1$
@@ -795,21 +778,21 @@
if (propertyAliasTable == null) {
propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256);
}
- propertyAliasTable.put(serviceName, aliasName
- .toUpperCase(), s);
+ propertyAliasTable.put(serviceName, Util.toUpperCase(aliasName
+ ), s);
}
}
continue;
}
- int j = key.indexOf("."); //$NON-NLS-1$
+ int j = key.indexOf('.');
if (j == -1) { // unknown format
continue;
}
- i = key.indexOf(" "); //$NON-NLS-1$
+ i = key.indexOf(' ');
if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className>
serviceName = key.substring(0, j);
algorithm = key.substring(j + 1);
- String alg = algorithm.toUpperCase();
+ String alg = Util.toUpperCase(algorithm);
Object o = null;
if (propertyServiceTable != null) {
o = propertyServiceTable.get(serviceName, alg);
@@ -834,7 +817,7 @@
serviceName = key.substring(0, j);
algorithm = key.substring(j + 1, i);
String attribute = key.substring(i + 1);
- String alg = algorithm.toUpperCase();
+ String alg = Util.toUpperCase(algorithm);
Object o = null;
if (propertyServiceTable != null) {
o = propertyServiceTable.get(serviceName, alg);
@@ -875,11 +858,12 @@
// These attributes should be placed in each Provider object:
// Provider.id name, Provider.id version, Provider.id info,
// Provider.id className
+ @SuppressWarnings("nls")
private void putProviderInfo() {
- super.put("Provider.id name", null != name ? name : "null"); //$NON-NLS-1$
- super.put("Provider.id version", versionString); //$NON-NLS-1$
- super.put("Provider.id info", null != info ? info : "null"); //$NON-NLS-1$
- super.put("Provider.id className", this.getClass().getName()); //$NON-NLS-1$
+ super.put("Provider.id name", null != name ? name : "null");
+ super.put("Provider.id version", versionString);
+ super.put("Provider.id info", null != info ? info : "null");
+ super.put("Provider.id className", this.getClass().getName());
}
// Searches for the property with the specified key in the provider
@@ -894,7 +878,7 @@
}
for (Enumeration<?> e = propertyNames(); e.hasMoreElements();) {
String pname = (String) e.nextElement();
- if (key.equalsIgnoreCase(pname)) {
+ if (Util.equalsIgnoreCase(key, pname)) {
return getProperty(pname);
}
}
@@ -905,8 +889,6 @@
* {@code Service} represents a service in the Java Security infrastructure.
* Each service describes its type, the algorithm it implements, to which
* provider it belongs and other properties.
- *
- * @since Android 1.0
*/
public static class Service {
// The provider
@@ -936,7 +918,7 @@
/**
* Constructs a new instance of {@code Service} with the given
* attributes.
- *
+ *
* @param provider
* the provider to which this service belongs.
* @param type
@@ -955,7 +937,6 @@
* @throws NullPointerException
* if {@code provider, type, algorithm} or {@code className}
* is {@code null}.
- * @since Android 1.0
*/
public Service(Provider provider, String type, String algorithm,
String className, List<String> aliases, Map<String, String> attributes) {
@@ -1006,21 +987,19 @@
/**
* Returns the type of this {@code Service}. For example {@code
* KeyPairGenerator}.
- *
+ *
* @return the type of this {@code Service}.
- * @since Android 1.0
*/
public final String getType() {
return type;
}
/**
- * Returns the name of the algorithm implemented by this {@code Service}
- * .
- *
- * @return the name of the algorithm implemented by this {@code Service}
- * .
- * @since Android 1.0
+ * Returns the name of the algorithm implemented by this {@code
+ * Service}.
+ *
+ * @return the name of the algorithm implemented by this {@code
+ * Service}.
*/
public final String getAlgorithm() {
return algorithm;
@@ -1028,9 +1007,8 @@
/**
* Returns the {@code Provider} this {@code Service} belongs to.
- *
+ *
* @return the {@code Provider} this {@code Service} belongs to.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -1038,9 +1016,8 @@
/**
* Returns the name of the class implementing this {@code Service}.
- *
+ *
* @return the name of the class implementing this {@code Service}.
- * @since Android 1.0
*/
public final String getClassName() {
return className;
@@ -1048,14 +1025,13 @@
/**
* Returns the value of the attribute with the specified {@code name}.
- *
+ *
* @param name
* the name of the attribute.
* @return the value of the attribute, or {@code null} if no attribute
* with the given name is set.
* @throws NullPointerException
* if {@code name} is {@code null}.
- * @since Android 1.0
*/
public final String getAttribute(String name) {
if (name == null) {
@@ -1068,13 +1044,16 @@
}
Iterator<String> getAliases() {
+ if(aliases == null){
+ aliases = new ArrayList<String>(0);
+ }
return aliases.iterator();
}
/**
* Creates and returns a new instance of the implementation described by
* this {@code Service}.
- *
+ *
* @param constructorParameter
* the parameter that is used by the constructor, or {@code
* null} if the implementation does not declare a constructor
@@ -1086,7 +1065,6 @@
* @throws InvalidParameterException
* if the implementation does not support the specified
* {@code constructorParameter}.
- * @since Android 1.0
*/
public Object newInstance(Object constructorParameter)
throws NoSuchAlgorithmException {
@@ -1122,39 +1100,37 @@
throw new NoSuchAlgorithmException(Messages.getString("security.199", //$NON-NLS-1$
type, algorithm), e);
}
- } else {
- if (!supportsParameter(constructorParameter)) {
- throw new InvalidParameterException(
- Messages.getString("security.12", type)); //$NON-NLS-1$
- }
+ }
+ if (!supportsParameter(constructorParameter)) {
+ throw new InvalidParameterException(
+ Messages.getString("security.12", type)); //$NON-NLS-1$
+ }
- Class[] parameterTypes = new Class[1];
- Object[] initargs = { constructorParameter };
- try {
- if (type.equalsIgnoreCase("CertStore")) { //$NON-NLS-1$
- parameterTypes[0] = Class
- .forName("java.security.cert.CertStoreParameters"); //$NON-NLS-1$
- } else {
- parameterTypes[0] = constructorParameter.getClass();
- }
- return implementation.getConstructor(parameterTypes)
- .newInstance(initargs);
- } catch (Exception e) {
- throw new NoSuchAlgorithmException(Messages.getString("security.199", //$NON-NLS-1$
- type, algorithm), e);
+ Class[] parameterTypes = new Class[1];
+ Object[] initargs = { constructorParameter };
+ try {
+ if (Util.equalsIgnoreCase(type,"CertStore")) { //$NON-NLS-1$
+ parameterTypes[0] = Class
+ .forName("java.security.cert.CertStoreParameters"); //$NON-NLS-1$
+ } else {
+ parameterTypes[0] = constructorParameter.getClass();
}
+ return implementation.getConstructor(parameterTypes)
+ .newInstance(initargs);
+ } catch (Exception e) {
+ throw new NoSuchAlgorithmException(Messages.getString("security.199", //$NON-NLS-1$
+ type, algorithm), e);
}
}
/**
* Indicates whether this {@code Service} supports the specified
* constructor parameter.
- *
+ *
* @param parameter
* the parameter to test.
* @return {@code true} if this {@code Service} supports the specified
* constructor parameter, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean supportsParameter(Object parameter) {
return true;
@@ -1163,10 +1139,10 @@
/**
* Returns a string containing a concise, human-readable description of
* this {@code Service}.
- *
+ *
* @return a printable representation for this {@code Service}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
String result = "Provider " + provider.getName() + " Service " //$NON-NLS-1$ //$NON-NLS-2$
+ type + "." + algorithm + " " + className; //$NON-NLS-1$ //$NON-NLS-2$
@@ -1179,4 +1155,10 @@
return result;
}
}
+
+ private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ versionString = String.valueOf(version);
+ providerNumber = -1;
+ }
}
diff --git a/security/src/main/java/java/security/ProviderException.java b/security/src/main/java/java/security/ProviderException.java
index d4def5b..22950f5 100644
--- a/security/src/main/java/java/security/ProviderException.java
+++ b/security/src/main/java/java/security/ProviderException.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
@@ -27,7 +22,6 @@
* Providers}.
*
* @see Provider
- * @since Android 1.0
*/
public class ProviderException extends RuntimeException {
@@ -36,10 +30,9 @@
/**
* Constructs a new instance of {@code ProviderException} with the given
* message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public ProviderException(String msg) {
super(msg);
@@ -47,8 +40,6 @@
/**
* Constructs a new instance of {@code ProviderException}.
- *
- * @since Android 1.0
*/
public ProviderException() {
}
@@ -56,12 +47,11 @@
/**
* Constructs a new instance of {@code ProviderException} with the given
* message and the cause.
- *
+ *
* @param message
* the detail message for this exception.
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public ProviderException(String message, Throwable cause) {
super(message, cause);
@@ -69,12 +59,11 @@
/**
* Constructs a new instance of {@code ProviderException} with the cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception.
- * @since Android 1.0
*/
public ProviderException(Throwable cause) {
super(cause);
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/PublicKey.java b/security/src/main/java/java/security/PublicKey.java
index 4888a64..c197840 100644
--- a/security/src/main/java/java/security/PublicKey.java
+++ b/security/src/main/java/java/security/PublicKey.java
@@ -15,25 +15,16 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code PublicKey} is the common interface for public keys.
*
* @see PrivateKey
- * @since Android 1.0
*/
public interface PublicKey extends Key {
-
/**
* The {@code serialVersionUID} to be compatible with JDK1.1.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = 7187392471159151072L;
}
diff --git a/security/src/main/java/java/security/SecureClassLoader.java b/security/src/main/java/java/security/SecureClassLoader.java
index 7d08fc8..07bebc9 100644
--- a/security/src/main/java/java/security/SecureClassLoader.java
+++ b/security/src/main/java/java/security/SecureClassLoader.java
@@ -15,28 +15,20 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
import java.nio.ByteBuffer;
import java.util.HashMap;
-
/**
* {@code SecureClassLoader} represents a {@code ClassLoader} which associates
* the classes it loads with a code source and provide mechanisms to allow the
* relevant permissions to be retrieved.
- *
- * @since Android 1.0
*/
public class SecureClassLoader extends ClassLoader {
// A cache of ProtectionDomains for a given CodeSource
- private HashMap pds = new HashMap();
+ private HashMap<CodeSource, ProtectionDomain> pds = new HashMap<CodeSource, ProtectionDomain>();
/**
* Constructs a new instance of {@code SecureClassLoader}. The default
@@ -45,12 +37,10 @@
* If a {@code SecurityManager} is installed, code calling this constructor
* needs the {@code SecurityPermission} {@code checkCreateClassLoader} to be
* granted, otherwise a {@code SecurityException} will be thrown.
- * </p>
- *
+ *
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this constructor.
- * @since Android 1.0
*/
protected SecureClassLoader() {
super();
@@ -63,14 +53,12 @@
* If a {@code SecurityManager} is installed, code calling this constructor
* needs the {@code SecurityPermission} {@code checkCreateClassLoader} to be
* granted, otherwise a {@code SecurityException} will be thrown.
- * </p>
- *
+ *
* @param parent
* the parent {@code ClassLoader}.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this constructor.
- * @since Android 1.0
*/
protected SecureClassLoader(ClassLoader parent) {
super(parent);
@@ -79,12 +67,11 @@
/**
* Returns the {@code PermissionCollection} for the specified {@code
* CodeSource}.
- *
+ *
* @param codesource
* the code source.
* @return the {@code PermissionCollection} for the specified {@code
* CodeSource}.
- * @since Android 1.0
*/
protected PermissionCollection getPermissions(CodeSource codesource) {
// Do nothing by default, ProtectionDomain will take care about
@@ -95,7 +82,7 @@
/**
* Constructs a new class from an array of bytes containing a class
* definition in class file format with an optional {@code CodeSource}.
- *
+ *
* @param name
* the name of the new class.
* @param b
@@ -116,7 +103,6 @@
* if the package to which this class is to be added, already
* contains classes which were signed by different certificates,
* or if the class name begins with "java."
- * @since Android 1.0
*/
protected final Class<?> defineClass(String name, byte[] b, int off, int len,
CodeSource cs) {
@@ -127,7 +113,7 @@
/**
* Constructs a new class from an array of bytes containing a class
* definition in class file format with an optional {@code CodeSource}.
- *
+ *
* @param name
* the name of the new class.
* @param b
@@ -141,7 +127,6 @@
* if the package to which this class is to be added, already
* contains classes which were signed by different certificates,
* or if the class name begins with "java."
- * @since Android 1.0
*/
protected final Class<?> defineClass(String name, ByteBuffer b, CodeSource cs) {
//FIXME 1.5 - remove b.array(), call super.defineClass(,ByteBuffer,)
@@ -165,7 +150,7 @@
// will have it's own ProtectionDomain, which does not look right.
ProtectionDomain pd;
synchronized (pds) {
- if ((pd = (ProtectionDomain) pds.get(cs)) != null) {
+ if ((pd = pds.get(cs)) != null) {
return pd;
}
PermissionCollection perms = getPermissions(cs);
diff --git a/security/src/main/java/java/security/SecureRandom.java b/security/src/main/java/java/security/SecureRandom.java
index e1d99e9..c697504 100644
--- a/security/src/main/java/java/security/SecureRandom.java
+++ b/security/src/main/java/java/security/SecureRandom.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.util.Iterator;
@@ -35,8 +30,6 @@
/**
* {@code SecureRandom} is an engine class which is capable of generating
* cryptographically secure pseudo-random numbers.
- *
- * @since Android 1.0
*/
public class SecureRandom extends Random {
@@ -50,7 +43,7 @@
private Provider provider;
- private SecureRandomSpi secureRandomSpi;
+ private SecureRandomSpi secureRandomSpi;
private String algorithm;
@@ -69,8 +62,6 @@
* Constructs a new instance of {@code SecureRandom}. An implementation for
* the highest-priority provider is returned. The constructed instance will
* not have been seeded.
- *
- * @since Android 1.0
*/
public SecureRandom() {
super(0);
@@ -97,7 +88,6 @@
*
* @param seed
* the seed for this generator.
- * @since Android 1.0
*/
public SecureRandom(byte[] seed) {
this();
@@ -125,7 +115,6 @@
* the implementation.
* @param provider
* the security provider.
- * @since Android 1.0
*/
protected SecureRandom(SecureRandomSpi secureRandomSpi,
Provider provider) {
@@ -154,7 +143,6 @@
* if the specified algorithm is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static SecureRandom getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -183,7 +171,6 @@
* if the specified provider is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static SecureRandom getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
@@ -212,7 +199,6 @@
* if the specified algorithm is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static SecureRandom getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
@@ -232,7 +218,6 @@
* Returns the provider associated with this {@code SecureRandom}.
*
* @return the provider associated with this {@code SecureRandom}.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -242,7 +227,6 @@
* Returns the name of the algorithm of this {@code SecureRandom}.
*
* @return the name of the algorithm of this {@code SecureRandom}.
- * @since Android 1.0
*/
public String getAlgorithm() {
return algorithm;
@@ -255,7 +239,6 @@
*
* @param seed
* the new seed.
- * @since Android 1.0
*/
public synchronized void setSeed(byte[] seed) {
secureRandomSpi.engineSetSeed(seed);
@@ -268,8 +251,8 @@
*
* @param seed
* the new seed.
- * @since Android 1.0
*/
+ @Override
public void setSeed(long seed) {
if (seed == 0) { // skip call from Random
return;
@@ -293,8 +276,8 @@
*
* @param bytes
* the {@code byte[]} to be filled with random bytes.
- * @since Android 1.0
*/
+ @Override
public synchronized void nextBytes(byte[] bytes) {
secureRandomSpi.engineNextBytes(bytes);
}
@@ -307,8 +290,8 @@
* number of bits to be generated. An input value should be in
* the range [0, 32].
* @return an {@code int} containing the specified number of random bits.
- * @since Android 1.0
*/
+ @Override
protected final int next(int numBits) {
if (numBits < 0) {
numBits = 0;
@@ -336,7 +319,6 @@
* @param numBytes
* the number of seed bytes.
* @return the seed bytes
- * @since Android 1.0
*/
public static byte[] getSeed(int numBytes) {
if (internalSecureRandom == null) {
@@ -352,7 +334,6 @@
* @param numBytes
* the number of seed bytes.
* @return the seed bytes.
- * @since Android 1.0
*/
public byte[] generateSeed(int numBytes) {
return secureRandomSpi.engineGenerateSeed(numBytes);
diff --git a/security/src/main/java/java/security/SecureRandomSpi.java b/security/src/main/java/java/security/SecureRandomSpi.java
index 7ce880c..829464f 100644
--- a/security/src/main/java/java/security/SecureRandomSpi.java
+++ b/security/src/main/java/java/security/SecureRandomSpi.java
@@ -15,21 +15,15 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.io.Serializable;
/**
* {@code SecureRandomSpi} is the <i>Service Provider Interface</i> (<b>SPI</b>) definition
- * for {@link SecureRandom}.
+ * for {@link SecureRandom}.
*
* @see SecureRandom
- * @since Android 1.0
*/
public abstract class SecureRandomSpi implements Serializable {
@@ -42,7 +36,6 @@
*
* @param seed
* the new seed.
- * @since Android 1.0
*/
protected abstract void engineSetSeed(byte[] seed);
@@ -52,7 +45,6 @@
*
* @param bytes
* the {@code byte[]} to be filled with random bytes.
- * @since Android 1.0
*/
protected abstract void engineNextBytes(byte[] bytes);
@@ -63,7 +55,6 @@
* @param numBytes
* the number of seed bytes.
* @return the seed bytes
- * @since Android 1.0
*/
protected abstract byte[] engineGenerateSeed(int numBytes);
}
diff --git a/security/src/main/java/java/security/Security.java b/security/src/main/java/java/security/Security.java
index 505a557..6ff38ad 100644
--- a/security/src/main/java/java/security/Security.java
+++ b/security/src/main/java/java/security/Security.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.io.BufferedInputStream;
@@ -39,7 +34,9 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.Map.Entry;
+import org.apache.harmony.security.Util;
import org.apache.harmony.security.fortress.Engine;
import org.apache.harmony.security.fortress.PolicyUtils;
import org.apache.harmony.security.fortress.SecurityAccess;
@@ -50,8 +47,6 @@
* {@code Security} is the central class in the Java Security API. It manages
* the list of security {@code Provider} that have been installed into this
* runtime environment.
- *
- * @since Android 1.0
*/
public final class Security {
@@ -87,57 +82,40 @@
// END android-added
// BEGIN android-removed
- // File f = new File(System.getProperty("java.home") //$NON-NLS-1$
- // + File.separator + "lib" + File.separator //$NON-NLS-1$
- // + "security" + File.separator + "java.security"); //$NON-NLS-1$ //$NON-NLS-2$
- // if (f.exists()) {
- // try {
- // FileInputStream fis = new FileInputStream(f);
- // InputStream is = new BufferedInputStream(fis);
- // secprops.load(is);
- // loaded = true;
- // is.close();
- // } catch (IOException e) {
- //// System.err.println("Could not load Security properties file: "
- //// + e);
- // }
- // }
- //
- // if ("true".equalsIgnoreCase(secprops.getProperty("security.allowCustomPropertiesFile", "true"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- // String securityFile = System.getProperty("java.security.properties"); //$NON-NLS-1$
- // if (securityFile != null) {
- // if (securityFile.startsWith("=")) { // overwrite //$NON-NLS-1$
- // secprops = new Properties();
- // loaded = false;
- // securityFile = securityFile.substring(1);
- // }
- // try {
- // securityFile = PolicyUtils.expand(securityFile, System.getProperties());
- // } catch (PolicyUtils.ExpansionFailedException e) {
- //// System.err.println("Could not load custom Security properties file "
- //// + securityFile +": " + e);
- // }
- // f = new File(securityFile);
- // InputStream is;
- // try {
- // if (f.exists()) {
- // FileInputStream fis = new FileInputStream(f);
- // is = new BufferedInputStream(fis);
- // } else {
- // URL url = new URL(securityFile);
- // is = new BufferedInputStream(url.openStream());
- // }
- // secprops.load(is);
- // loaded = true;
- // is.close();
- // } catch (IOException e) {
- // // System.err.println("Could not load custom Security properties file "
- // // + securityFile +": " + e);
- // }
- // }
- // }
+// if (Util.equalsIgnoreCase("true", secprops.getProperty("security.allowCustomPropertiesFile", "true"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+// String securityFile = System.getProperty("java.security.properties"); //$NON-NLS-1$
+// if (securityFile != null) {
+// if (securityFile.startsWith("=")) { // overwrite //$NON-NLS-1$
+// secprops = new Properties();
+// loaded = false;
+// securityFile = securityFile.substring(1);
+// }
+// try {
+// securityFile = PolicyUtils.expand(securityFile, System.getProperties());
+// } catch (PolicyUtils.ExpansionFailedException e) {
+//// System.err.println("Could not load custom Security properties file "
+//// + securityFile +": " + e);
+// }
+// f = new File(securityFile);
+// InputStream is;
+// try {
+// if (f.exists()) {
+// FileInputStream fis = new FileInputStream(f);
+// is = new BufferedInputStream(fis);
+// } else {
+// URL url = new URL(securityFile);
+// is = new BufferedInputStream(url.openStream());
+// }
+// secprops.load(is);
+// loaded = true;
+// is.close();
+// } catch (IOException e) {
+// // System.err.println("Could not load custom Security properties file "
+// // + securityFile +": " + e);
+// }
+// }
+// }
// END android-removed
-
if (!loaded) {
registerDefaultProviders();
}
@@ -161,12 +139,9 @@
secprops.put("security.provider.4", "org.bouncycastle.jce.provider.BouncyCastleProvider"); //$NON-NLS-1$ //$NON-NLS-2$
}
- // BEGIN android-note
- // added Deprecated annotation
- // END android-note
/**
* Returns value for the specified algorithm with the specified name.
- *
+ *
* @param algName
* the name of the algorithm.
* @param propName
@@ -174,7 +149,6 @@
* @return value of the property.
* @deprecated Use {@link AlgorithmParameters} and {@link KeyFactory}
* instead.
- * @since Android 1.0
*/
@Deprecated
public static String getAlgorithmProperty(String algName, String propName) {
@@ -189,7 +163,7 @@
for (Enumeration e = providers[i].propertyNames(); e
.hasMoreElements();) {
String pname = (String) e.nextElement();
- if (prop.equalsIgnoreCase(pname)) {
+ if (Util.equalsIgnoreCase(prop, pname)) {
return providers[i].getProperty(pname);
}
}
@@ -206,8 +180,7 @@
* the {@code SecurityPermission} {@code insertProvider.NAME} (where NAME is
* the provider name) to be granted, otherwise a {@code SecurityException}
* will be thrown.
- * </p>
- *
+ *
* @param provider
* the provider to insert.
* @param position
@@ -218,7 +191,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public static synchronized int insertProviderAt(Provider provider,
int position) {
@@ -246,8 +218,7 @@
* the {@code SecurityPermission} {@code insertProvider.NAME} (where NAME is
* the provider name) to be granted, otherwise a {@code SecurityException}
* will be thrown.
- * </p>
- *
+ *
* @param provider
* the provider to be added.
* @return the actual position or {@code -1} if the given {@code provider}
@@ -255,7 +226,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public static int addProvider(Provider provider) {
return insertProviderAt(provider, 0);
@@ -269,20 +239,17 @@
* <p>
* Returns silently if {@code name} is {@code null} or no provider with the
* specified name is installed.
- * </p>
* <p>
* If a {@code SecurityManager} is installed, code calling this method needs
* the {@code SecurityPermission} {@code removeProvider.NAME} (where NAME is
* the provider name) to be granted, otherwise a {@code SecurityException}
* will be thrown.
- * </p>
- *
+ *
* @param name
* the name of the provider to remove.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public static synchronized void removeProvider(String name) {
// It is not clear from spec.:
@@ -311,9 +278,8 @@
/**
* Returns an array containing all installed providers. The providers are
* ordered according their preference order.
- *
+ *
* @return an array containing all installed providers.
- * @since Android 1.0
*/
public static synchronized Provider[] getProviders() {
return Services.getProviders();
@@ -323,11 +289,10 @@
* Returns the {@code Provider} with the specified name. Returns {@code
* null} if name is {@code null} or no provider with the specified name is
* installed.
- *
+ *
* @param name
* the name of the requested provider.
* @return the provider with the specified name, maybe {@code null}.
- * @since Android 1.0
*/
public static synchronized Provider getProvider(String name) {
return Services.getProvider(name);
@@ -337,15 +302,15 @@
* Returns the array of providers which meet the user supplied string
* filter. The specified filter must be supplied in one of two formats:
* <nl>
- * <li> CRYPTO_SERVICE_NAME.ALGORITHM_OR_TYPE
+ * <li> CRYPTO_SERVICE_NAME.ALGORITHM_OR_TYPE
* <p>
- * (for example: "MessageDigest.SHA")
+ * (for example: "MessageDigest.SHA")
* <li> CRYPTO_SERVICE_NAME.ALGORITHM_OR_TYPE
* ATTR_NAME:ATTR_VALUE
* <p>
- * (for example: "Signature.MD5withRSA KeySize:512")
+ * (for example: "Signature.MD2withRSA KeySize:512")
* </nl>
- *
+ *
* @param filter
* case-insensitive filter.
* @return the providers which meet the user supplied string filter {@code
@@ -355,7 +320,6 @@
* if an unusable filter is supplied.
* @throws NullPointerException
* if {@code filter} is {@code null}.
- * @since Android 1.0
*/
public static Provider[] getProviders(String filter) {
if (filter == null) {
@@ -366,7 +330,7 @@
Messages.getString("security.2B")); //$NON-NLS-1$
}
HashMap<String, String> hm = new HashMap<String, String>();
- int i = filter.indexOf(":"); //$NON-NLS-1$
+ int i = filter.indexOf(':');
if ((i == filter.length() - 1) || (i == 0)) {
throw new InvalidParameterException(
Messages.getString("security.2B")); //$NON-NLS-1$
@@ -389,10 +353,10 @@
* be an empty string. <li> CRYPTO_SERVICE_NAME.ALGORITHM_OR_TYPE
* ATTR_NAME:ATTR_VALUE
* <p>
- * for example: "Signature.MD5withRSA KeySize:512" where "KeySize:512" is
+ * for example: "Signature.MD2withRSA KeySize:512" where "KeySize:512" is
* the value of the filter map entry.
* </nl>
- *
+ *
* @param filter
* case-insensitive filter.
* @return the providers which meet the user supplied string filter {@code
@@ -402,7 +366,6 @@
* if an unusable filter is supplied.
* @throws NullPointerException
* if {@code filter} is {@code null}.
- * @since Android 1.0
*/
public static synchronized Provider[] getProviders(Map<String,String> filter) {
if (filter == null) {
@@ -412,15 +375,15 @@
return null;
}
java.util.List<Provider> result = Services.getProvidersList();
- Set keys = filter.entrySet();
- Map.Entry entry;
- for (Iterator it = keys.iterator(); it.hasNext();) {
- entry = (Map.Entry) it.next();
- String key = (String) entry.getKey();
- String val = (String) entry.getValue();
+ Set<Entry<String, String>> keys = filter.entrySet();
+ Map.Entry<String, String> entry;
+ for (Iterator<Entry<String, String>> it = keys.iterator(); it.hasNext();) {
+ entry = it.next();
+ String key = entry.getKey();
+ String val = entry.getValue();
String attribute = null;
- int i = key.indexOf(" "); //$NON-NLS-1$
- int j = key.indexOf("."); //$NON-NLS-1$
+ int i = key.indexOf(' ');
+ int j = key.indexOf('.');
if (j == -1) {
throw new InvalidParameterException(
Messages.getString("security.2B")); //$NON-NLS-1$
@@ -451,7 +414,7 @@
Provider p;
for (int k = 0; k < result.size(); k++) {
try {
- p = (Provider) result.get(k);
+ p = result.get(k);
} catch (IndexOutOfBoundsException e) {
break;
}
@@ -463,9 +426,8 @@
}
if (result.size() > 0) {
return result.toArray(new Provider[result.size()]);
- } else {
- return null;
}
+ return null;
}
/**
@@ -475,15 +437,13 @@
* the {@code SecurityPermission} {@code getProperty.KEY} (where KEY is the
* specified {@code key}) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- * </p>
- *
+ *
* @param key
* the name of the requested security property.
* @return the value of the security property.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public static String getProperty(String key) {
if (key == null) {
@@ -493,7 +453,11 @@
if (sm != null) {
sm.checkSecurityAccess("getProperty." + key); //$NON-NLS-1$
}
- return secprops.getProperty(key);
+ String property = secprops.getProperty(key);
+ if (property != null) {
+ property = property.trim();
+ }
+ return property;
}
/**
@@ -503,8 +467,7 @@
* the {@code SecurityPermission} {@code setProperty.KEY} (where KEY is the
* specified {@code key}) to be granted, otherwise a {@code
* SecurityException} will be thrown.
- * </p>
- *
+ *
* @param key
* the name of the security property.
* @param datnum
@@ -512,7 +475,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public static void setProperty(String key, String datnum) {
SecurityManager sm = System.getSecurityManager();
@@ -526,22 +488,27 @@
* Returns a {@code Set} of all registered algorithms for the specified
* cryptographic service. {@code "Signature"}, {@code "Cipher"} and {@code
* "KeyStore"} are examples for such kind of services.
- *
+ *
* @param serviceName
* the case-insensitive name of the service.
* @return a {@code Set} of all registered algorithms for the specified
* cryptographic service, or an empty {@code Set} if {@code
* serviceName} is {@code null} or if no registered provider
* provides the requested service.
- * @since Android 1.0
*/
public static Set<String> getAlgorithms(String serviceName) {
Set<String> result = new HashSet<String>();
+ // BEGIN android-added
+ // compatibility with RI
+ if (serviceName == null) {
+ return result;
+ }
+ // END android-added
Provider[] p = getProviders();
for (int i = 0; i < p.length; i++) {
for (Iterator it = p[i].getServices().iterator(); it.hasNext();) {
Provider.Service s = (Provider.Service) it.next();
- if (s.getType().equalsIgnoreCase(serviceName)) {
+ if (Util.equalsIgnoreCase(s.getType(),serviceName)) {
result.add(s.getAlgorithm());
}
}
diff --git a/security/src/main/java/java/security/SecurityPermission.java b/security/src/main/java/java/security/SecurityPermission.java
index 87f3aaa..599ec6f 100644
--- a/security/src/main/java/java/security/SecurityPermission.java
+++ b/security/src/main/java/java/security/SecurityPermission.java
@@ -15,18 +15,11 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
/**
* {@code SecurityPermission} objects guard access to the mechanisms which
* implement security. Security permissions have names, but not actions.
- *
- * @since Android 1.0
*/
public final class SecurityPermission extends BasicPermission {
@@ -35,10 +28,9 @@
/**
* Constructs a new instance of {@code SecurityPermission} with the given
* name.
- *
+ *
* @param name
* the name of the permission.
- * @since Android 1.0
*/
public SecurityPermission(String name) {
super(name);
@@ -48,12 +40,11 @@
* Constructs a new instance of {@code SecurityPermission} with the given
* {@code name} and {@code action} list. The action list is ignored - it is
* existing for compatibility reasons only.
- *
+ *
* @param name
* the name of the permission.
* @param action
* ignored.
- * @since Android 1.0
*/
public SecurityPermission(String name, String action) {
super(name, action);
diff --git a/security/src/main/java/java/security/Signature.java b/security/src/main/java/java/security/Signature.java
index e5d488e..4e3fe14 100644
--- a/security/src/main/java/java/security/Signature.java
+++ b/security/src/main/java/java/security/Signature.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.nio.ByteBuffer;
@@ -39,7 +34,6 @@
* registered with the {@link Security} class.
*
* @see SignatureSpi
- * @since Android 1.0
*/
public abstract class Signature extends SignatureSpi {
@@ -58,24 +52,18 @@
/**
* Constant that indicates that this {@code Signature} instance has not yet
* been initialized.
- *
- * @since Android 1.0
*/
protected static final int UNINITIALIZED = 0;
/**
* Constant that indicates that this {@code Signature} instance has been
* initialized for signing.
- *
- * @since Android 1.0
*/
protected static final int SIGN = 2;
/**
* Constant that indicates that this {@code Signature} instance has been
* initialized for verification.
- *
- * @since Android 1.0
*/
protected static final int VERIFY = 3;
@@ -83,18 +71,15 @@
* Represents the current state of this {@code Signature}. The three
* possible states are {@link #UNINITIALIZED}, {@link #SIGN} or
* {@link #VERIFY}.
- *
- * @since Android 1.0
*/
protected int state = UNINITIALIZED;
/**
* Constructs a new instance of {@code Signature} with the name of
* the algorithm to use.
- *
+ *
* @param algorithm
* the name of algorithm to use.
- * @since Android 1.0
*/
protected Signature(String algorithm) {
this.algorithm = algorithm;
@@ -103,7 +88,7 @@
/**
* Returns a new instance of {@code Signature} that utilizes the specified
* algorithm.
- *
+ *
* @param algorithm
* the name of the algorithm to use.
* @return a new instance of {@code Signature} that utilizes the specified
@@ -112,7 +97,6 @@
* if the specified algorithm is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static Signature getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -137,7 +121,7 @@
/**
* Returns a new instance of {@code Signature} that utilizes the specified
* algorithm from the specified provider.
- *
+ *
* @param algorithm
* the name of the algorithm to use.
* @param provider
@@ -150,7 +134,6 @@
* if the specified provider is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static Signature getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
@@ -171,7 +154,7 @@
/**
* Returns a new instance of {@code Signature} that utilizes the specified
* algorithm from the specified provider.
- *
+ *
* @param algorithm
* the name of the algorithm to use.
* @param provider
@@ -182,7 +165,6 @@
* if the specified algorithm is not available.
* @throws NullPointerException
* if {@code algorithm} is {@code null}.
- * @since Android 1.0
*/
public static Signature getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
@@ -214,9 +196,8 @@
/**
* Returns the provider associated with this {@code Signature}.
- *
+ *
* @return the provider associated with this {@code Signature}.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -224,9 +205,8 @@
/**
* Returns the name of the algorithm of this {@code Signature}.
- *
+ *
* @return the name of the algorithm of this {@code Signature}.
- * @since Android 1.0
*/
public final String getAlgorithm() {
return algorithm;
@@ -236,12 +216,11 @@
* Initializes this {@code Signature} instance for signature verification,
* using the public key of the identity whose signature is going to be
* verified.
- *
+ *
* @param publicKey
* the public key.
* @throws InvalidKeyException
* if {@code publicKey} is not valid.
- * @since Android 1.0
*/
public final void initVerify(PublicKey publicKey)
throws InvalidKeyException {
@@ -257,14 +236,12 @@
* If the given certificate is an instance of {@link X509Certificate} and
* has a key usage parameter that indicates, that this certificate is not to
* be used for signing, an {@code InvalidKeyException} is thrown.
- * </p>
- *
+ *
* @param certificate
* the certificate used to verify a signature.
* @throws InvalidKeyException
* if the publicKey in the certificate is not valid or not to be
* used for signing.
- * @since Android 1.0
*/
public final void initVerify(Certificate certificate)
throws InvalidKeyException {
@@ -302,12 +279,11 @@
/**
* Initializes this {@code Signature} instance for signing, using the
* private key of the identity whose signature is going to be generated.
- *
+ *
* @param privateKey
* the private key.
* @throws InvalidKeyException
* if {@code privateKey} is not valid.
- * @since Android 1.0
*/
public final void initSign(PrivateKey privateKey)
throws InvalidKeyException {
@@ -319,14 +295,13 @@
* Initializes this {@code Signature} instance for signing, using the
* private key of the identity whose signature is going to be generated and
* the specified source of randomness.
- *
+ *
* @param privateKey
* the private key.
* @param random
* the {@code SecureRandom} to use.
* @throws InvalidKeyException
* if {@code privateKey} is not valid.
- * @since Android 1.0
*/
public final void initSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
@@ -340,13 +315,11 @@
* This {@code Signature} instance is reset to the state of its last
* initialization for signing and thus can be used for another signature
* from the same identity.
- * </p>
- *
+ *
* @return the signature of all updated data.
* @throws SignatureException
* if this {@code Signature} instance is not initialized
* properly.
- * @since Android 1.0
*/
public final byte[] sign() throws SignatureException {
if (state != SIGN) {
@@ -363,8 +336,7 @@
* This {@code Signature} instance is reset to the state of its last
* initialization for signing and thus can be used for another signature
* from the same identity.
- * </p>
- *
+ *
* @param outbuf
* the buffer to store the signature.
* @param offset
@@ -378,7 +350,6 @@
* @throws IllegalArgumentException
* if {@code offset} or {@code len} are not valid in respect to
* {@code outbuf}.
- * @since Android 1.0
*/
public final int sign(byte[] outbuf, int offset, int len)
throws SignatureException {
@@ -401,8 +372,7 @@
* This {@code Signature} instance is reset to the state of its last
* initialization for verifying and thus can be used to verify another
* signature of the same signer.
- * </p>
- *
+ *
* @param signature
* the signature to verify.
* @return {@code true} if the signature was verified, {@code false}
@@ -410,7 +380,6 @@
* @throws SignatureException
* if this {@code Signature} instance is not initialized
* properly.
- * @since Android 1.0
*/
public final boolean verify(byte[] signature) throws SignatureException {
if (state != VERIFY) {
@@ -428,8 +397,7 @@
* This {@code Signature} instance is reset to the state of its last
* initialization for verifying and thus can be used to verify another
* signature of the same signer.
- * </p>
- *
+ *
* @param signature
* the {@code byte[]} containing the signature to verify.
* @param offset
@@ -444,7 +412,6 @@
* @throws IllegalArgumentException
* if {@code offset} or {@code length} are not valid in respect
* to {@code signature}.
- * @since Android 1.0
*/
public final boolean verify(byte[] signature, int offset, int length)
throws SignatureException {
@@ -463,13 +430,12 @@
/**
* Updates the data to be verified or to be signed, using the specified
* {@code byte}.
- *
+ *
* @param b
* the byte to update with.
* @throws SignatureException
* if this {@code Signature} instance is not initialized
* properly.
- * @since Android 1.0
*/
public final void update(byte b) throws SignatureException {
if (state == UNINITIALIZED) {
@@ -482,13 +448,12 @@
/**
* Updates the data to be verified or to be signed, using the specified
* {@code byte[]}.
- *
+ *
* @param data
* the byte array to update with.
* @throws SignatureException
* if this {@code Signature} instance is not initialized
* properly.
- * @since Android 1.0
*/
public final void update(byte[] data) throws SignatureException {
if (state == UNINITIALIZED) {
@@ -501,7 +466,7 @@
/**
* Updates the data to be verified or to be signed, using the given {@code
* byte[]}, starting form the specified index for the specified length.
- *
+ *
* @param data
* the byte array to update with.
* @param off
@@ -511,7 +476,6 @@
* @throws SignatureException
* if this {@code Signature} instance is not initialized
* properly.
- * @since Android 1.0
*/
public final void update(byte[] data, int off, int len)
throws SignatureException {
@@ -530,13 +494,12 @@
/**
* Updates the data to be verified or to be signed, using the specified
* {@code ByteBuffer}.
- *
+ *
* @param data
* the {@code ByteBuffer} to update with.
* @throws SignatureException
* if this {@code Signature} instance is not initialized
* properly.
- * @since Android 1.0
*/
public final void update(ByteBuffer data) throws SignatureException {
if (state == UNINITIALIZED) {
@@ -549,10 +512,10 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code Signature} including its algorithm and its state.
- *
+ *
* @return a printable representation for this {@code Signature}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
return "SIGNATURE " + algorithm + " state: " + stateToString(state); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -571,12 +534,9 @@
}
}
- // BEGIN android-note
- // added Deprecated annotation
- // END android-note
/**
* Sets the specified parameter to the given value.
- *
+ *
* @param param
* the name of the parameter.
* @param value
@@ -585,7 +545,6 @@
* if the parameter is invalid, already set or is not allowed to
* be changed.
* @deprecated Use {@link #setParameter(AlgorithmParameterSpec)}
- * @since Android 1.0
*/
@Deprecated
public final void setParameter(String param, Object value)
@@ -595,13 +554,12 @@
/**
* Sets the specified {@code AlgorithmParameterSpec}.
- *
+ *
* @param params
* the parameter to set.
* @throws InvalidAlgorithmParameterException
* if the parameter is invalid, already set or is not allowed to
* be changed.
- * @since Android 1.0
*/
public final void setParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
@@ -611,18 +569,14 @@
/**
* Returns the {@code AlgorithmParameters} of this {@link Signature}
* instance.
- *
+ *
* @return the {@code AlgorithmParameters} of this {@link Signature}
* instance, maybe {@code null}.
- * @since Android 1.0
*/
public final AlgorithmParameters getParameters() {
return engineGetParameters();
}
- // BEGIN android-note
- // added Deprecated annotation
- // END android-note
/**
* Returns the value of the parameter with the specified name.
*
@@ -634,7 +588,6 @@
* if {@code param} is not a valid parameter for this {@code
* Signature} or an other error occures.
* @deprecated There is no generally accepted parameter naming convention.
- * @since Android 1.0
*/
@Deprecated
public final Object getParameter(String param)
@@ -642,12 +595,12 @@
return engineGetParameter(param);
}
+ @Override
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
- } else {
- throw new CloneNotSupportedException();
}
+ throw new CloneNotSupportedException();
}
/**
@@ -668,58 +621,66 @@
}
// engineSign() implementation
+ @Override
protected byte[] engineSign() throws SignatureException {
return spiImpl.engineSign();
}
// engineUpdate() implementation
+ @Override
protected void engineUpdate(byte arg0) throws SignatureException {
spiImpl.engineUpdate(arg0);
}
// engineVerify() implementation
+ @Override
protected boolean engineVerify(byte[] arg0) throws SignatureException {
return spiImpl.engineVerify(arg0);
}
// engineUpdate() implementation
+ @Override
protected void engineUpdate(byte[] arg0, int arg1, int arg2)
throws SignatureException {
spiImpl.engineUpdate(arg0, arg1, arg2);
}
// engineInitSign() implementation
+ @Override
protected void engineInitSign(PrivateKey arg0)
throws InvalidKeyException {
spiImpl.engineInitSign(arg0);
}
// engineInitVerify() implementation
+ @Override
protected void engineInitVerify(PublicKey arg0)
throws InvalidKeyException {
spiImpl.engineInitVerify(arg0);
}
// engineGetParameter() implementation
+ @Override
protected Object engineGetParameter(String arg0)
throws InvalidParameterException {
return spiImpl.engineGetParameter(arg0);
}
// engineSetParameter() implementation
+ @Override
protected void engineSetParameter(String arg0, Object arg1)
throws InvalidParameterException {
spiImpl.engineSetParameter(arg0, arg1);
}
// Returns a clone if the spiImpl is cloneable
+ @Override
public Object clone() throws CloneNotSupportedException {
if (spiImpl instanceof Cloneable) {
SignatureSpi spi = (SignatureSpi) spiImpl.clone();
return new SignatureImpl(spi, getProvider(), getAlgorithm());
- } else {
- throw new CloneNotSupportedException();
}
+ throw new CloneNotSupportedException();
}
}
}
diff --git a/security/src/main/java/java/security/SignatureException.java b/security/src/main/java/java/security/SignatureException.java
index f07c34b..f8909d1 100644
--- a/security/src/main/java/java/security/SignatureException.java
+++ b/security/src/main/java/java/security/SignatureException.java
@@ -15,18 +15,12 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
*{@code SignatureException} is a general {@code Signature} exception.
*
* @see Signature
- * @since Android 1.0
*/
public class SignatureException extends GeneralSecurityException {
@@ -35,10 +29,9 @@
/**
* Constructs a new instance of {@code SignatureException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public SignatureException(String msg) {
super(msg);
@@ -46,8 +39,6 @@
/**
* Constructs a new instance of {@code SignatureException}.
- *
- * @since Android 1.0
*/
public SignatureException() {
}
@@ -55,12 +46,11 @@
/**
* Constructs a new instance of {@code SignatureException} with the
* given message and the cause.
- *
+ *
* @param message
* the detail message for this exception
* @param cause
* the exception which is the cause for this exception
- * @since Android 1.0
*/
public SignatureException(String message, Throwable cause) {
super(message, cause);
@@ -69,10 +59,9 @@
/**
* Constructs a new instance of {@code SignatureException} with the
* cause.
- *
+ *
* @param cause
* the exception which is the cause for this exception
- * @since Android 1.0
*/
public SignatureException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/SignatureSpi.java b/security/src/main/java/java/security/SignatureSpi.java
index 738d489..93c9e8c 100644
--- a/security/src/main/java/java/security/SignatureSpi.java
+++ b/security/src/main/java/java/security/SignatureSpi.java
@@ -14,10 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
package java.security;
@@ -31,14 +27,11 @@
* definition for {@link Signature}.
*
* @see Signature
- * @since Android 1.0
*/
public abstract class SignatureSpi {
/**
* Implementation specific source of randomness.
- *
- * @since Android 1.0
*/
protected SecureRandom appRandom;
@@ -46,12 +39,11 @@
* Initializes this {@code SignatureSpi} instance for signature
* verification, using the public key of the identity whose signature is
* going to be verified.
- *
+ *
* @param publicKey
* the public key.
* @throws InvalidKeyException
* if {@code publicKey} is not valid.
- * @since Android 1.0
*/
protected abstract void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException;
@@ -59,12 +51,11 @@
/**
* Initializes this {@code SignatureSpi} instance for signing, using the
* private key of the identity whose signature is going to be generated.
- *
+ *
* @param privateKey
* the private key.
* @throws InvalidKeyException
* if {@code privateKey} is not valid.
- * @since Android 1.0
*/
protected abstract void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException;
@@ -73,14 +64,13 @@
* Initializes this {@code SignatureSpi} instance for signing, using the
* private key of the identity whose signature is going to be generated and
* the specified source of randomness.
- *
+ *
* @param privateKey
* the private key.
* @param random
* the {@code SecureRandom} to use.
* @throws InvalidKeyException
* if {@code privateKey} is not valid.
- * @since Android 1.0
*/
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
@@ -91,20 +81,19 @@
/**
* Updates the data to be verified or to be signed, using the specified
* {@code byte}.
- *
+ *
* @param b
* the byte to update with.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
- * @since Android 1.0
*/
protected abstract void engineUpdate(byte b) throws SignatureException;
/**
* Updates the data to be verified or to be signed, using the given {@code
* byte[]}, starting form the specified index for the specified length.
- *
+ *
* @param b
* the byte array to update with.
* @param off
@@ -114,7 +103,6 @@
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
- * @since Android 1.0
*/
protected abstract void engineUpdate(byte[] b, int off, int len)
throws SignatureException;
@@ -130,7 +118,6 @@
* method it throws a {@code RuntimeException} if underlying
* {@link #engineUpdate(byte[], int, int)} throws {@code
* SignatureException}.
- * @since Android 1.0
*/
protected void engineUpdate(ByteBuffer input) {
if (!input.hasRemaining()) {
@@ -165,13 +152,11 @@
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for signing and thus can be used for another signature
* from the same identity.
- * </p>
- *
+ *
* @return the signature of all updated data.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
- * @since Android 1.0
*/
protected abstract byte[] engineSign() throws SignatureException;
@@ -182,8 +167,7 @@
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for signing and thus can be used for another signature
* from the same identity.
- * </p>
- *
+ *
* @param outbuf
* the buffer to store the signature.
* @param offset
@@ -197,7 +181,6 @@
* @throws IllegalArgumentException
* if {@code offset} or {@code len} are not valid in respect to
* {@code outbuf}.
- * @since Android 1.0
*/
protected int engineSign(byte[] outbuf, int offset, int len)
throws SignatureException {
@@ -225,8 +208,7 @@
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for verifying and thus can be used to verify another
* signature of the same signer.
- * </p>
- *
+ *
* @param sigBytes
* the signature to verify.
* @return {@code true} if the signature was verified, {@code false}
@@ -234,7 +216,6 @@
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
- * @since Android 1.0
*/
protected abstract boolean engineVerify(byte[] sigBytes)
throws SignatureException;
@@ -247,8 +228,7 @@
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for verifying and thus can be used to verify another
* signature of the same signer.
- * </p>
- *
+ *
* @param sigBytes
* the {@code byte[]} containing the signature to verify.
* @param offset
@@ -263,7 +243,6 @@
* @throws IllegalArgumentException
* if {@code offset} or {@code length} are not valid in respect
* to {@code sigBytes}.
- * @since Android 1.0
*/
protected boolean engineVerify(byte[] sigBytes, int offset, int length)
throws SignatureException {
@@ -274,7 +253,7 @@
/**
* Sets the specified parameter to the given value.
- *
+ *
* @param param
* the name of the parameter.
* @param value
@@ -283,7 +262,6 @@
* if the parameter is invalid, already set or is not allowed to
* be changed.
* @deprecated Use {@link #engineSetParameter(AlgorithmParameterSpec)}
- * @since Android 1.0
*/
@Deprecated
protected abstract void engineSetParameter(String param, Object value)
@@ -291,13 +269,12 @@
/**
* Sets the specified {@code AlgorithmParameterSpec}.
- *
+ *
* @param params
* the parameter to set.
* @throws InvalidAlgorithmParameterException
* if the parameter is invalid, already set or is not allowed to
* be changed.
- * @since Android 1.0
*/
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
@@ -307,21 +284,17 @@
/**
* Returns the {@code AlgorithmParameters} of this {@link SignatureSpi}
* instance.
- *
+ *
* @return the {@code AlgorithmParameters} of this {@link SignatureSpi}
* instance, maybe {@code null}.
- * @since Android 1.0
*/
protected AlgorithmParameters engineGetParameters() {
throw new UnsupportedOperationException();
}
- // BEGIN android-note
- // added Deprecated annotation
- // END android-note
/**
* Returns the value of the parameter with the specified name.
- *
+ *
* @param param
* the name of the requested parameter value.
* @return the value of the parameter with the specified name, maybe {@code
@@ -330,17 +303,16 @@
* if {@code param} is not a valid parameter for this {@code
* SignatureSpi} or an other error occurs.
* @deprecated There is no generally accepted parameter naming convention.
- * @since Android 1.0
*/
@Deprecated
protected abstract Object engineGetParameter(String param)
throws InvalidParameterException;
+ @Override
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
- } else {
- throw new CloneNotSupportedException();
}
+ throw new CloneNotSupportedException();
}
}
diff --git a/security/src/main/java/java/security/SignedObject.java b/security/src/main/java/java/security/SignedObject.java
index d2022c8..3347cf3 100644
--- a/security/src/main/java/java/security/SignedObject.java
+++ b/security/src/main/java/java/security/SignedObject.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package java.security;
import java.io.ByteArrayInputStream;
@@ -33,8 +28,6 @@
* A {@code SignedObject} instance acts as a container for another object. The
* {@code SignedObject} contains the target in serialized form along with a
* digital signature of the serialized data.
- *
- * @since Android 1.0
*/
public final class SignedObject implements Serializable {
@@ -75,7 +68,6 @@
* if the private key is not valid.
* @throws SignatureException
* if signature generation failed.
- * @since Android 1.0
*/
public SignedObject(Serializable object, PrivateKey signingKey,
Signature signingEngine) throws IOException, InvalidKeyException,
@@ -106,7 +98,6 @@
* if deserialization failed.
* @throws ClassNotFoundException
* if the class of the encapsulated object can not be found.
- * @since Android 1.0
*/
public Object getObject() throws IOException, ClassNotFoundException {
// deserialize our object
@@ -123,7 +114,6 @@
* Returns the signature data of the encapsulated serialized object.
*
* @return the signature data of the encapsulated serialized object.
- * @since Android 1.0
*/
public byte[] getSignature() {
byte[] sig = new byte[signature.length];
@@ -135,7 +125,6 @@
* Returns the name of the algorithm of this {@code SignedObject}.
*
* @return the name of the algorithm of this {@code SignedObject}.
- * @since Android 1.0
*/
public String getAlgorithm() {
return thealgorithm;
@@ -155,7 +144,6 @@
* if the public key is invalid.
* @throws SignatureException
* if signature verification failed.
- * @since Android 1.0
*/
public boolean verify(PublicKey verificationKey,
Signature verificationEngine) throws InvalidKeyException,
@@ -166,4 +154,4 @@
return verificationEngine.verify(signature);
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/Signer.java b/security/src/main/java/java/security/Signer.java
index 9e48226..64996bf 100644
--- a/security/src/main/java/java/security/Signer.java
+++ b/security/src/main/java/java/security/Signer.java
@@ -15,16 +15,8 @@
* limitations under the License.
*/
-/**
- * @author Aleksei Y. Semenov
- * @version $Revision$
- */
-
package java.security;
-// BEGIN android-note
-// added Deprecated annotation
-// END android-note
/**
* {@link Signer} represents an identity (individual or corporation) that owns a
* private key and the corresponding public key.
@@ -32,7 +24,6 @@
* @deprecated Replaced by behavior in {@link java.security.cert
* java.security.cert} package and {@link java.security.Principal
* Principal}
- * @since Android 1.0
*/
@Deprecated
public abstract class Signer extends Identity {
@@ -43,8 +34,6 @@
/**
* Constructs a new instance of {@code Signer}.
- *
- * @since Android 1.0
*/
protected Signer() {
super();
@@ -52,10 +41,9 @@
/**
* Constructs a new instance of {@code Signer} with the given name.
- *
+ *
* @param name
* the name of the signer.
- * @since Android 1.0
*/
public Signer(String name) {
super(name);
@@ -64,7 +52,7 @@
/**
* Constructs a new instance of {@code Signer} with the given name in the
* given scope.
- *
+ *
* @param name
* the name of the signer.
* @param scope
@@ -72,7 +60,6 @@
* @throws KeyManagementException
* if a signer with the specified name already exists in the
* provided scope.
- * @since Android 1.0
*/
public Signer(String name, IdentityScope scope)
throws KeyManagementException {
@@ -84,12 +71,11 @@
* SecurityManager} is installed, code calling this method needs the {@code
* SecurityPermission} {@code "getSignerPrivateKey"} to be granted, otherwise
* a {@code SecurityException} will be thrown.
- *
+ *
* @return the private key of this {@code Signer}.
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public PrivateKey getPrivateKey() {
SecurityManager sm = System.getSecurityManager();
@@ -105,7 +91,7 @@
* SecurityManager} is installed, code calling this method needs the {@code
* SecurityPermission} {@code getSignerPrivateKey} to be granted, otherwise
* a {@code SecurityException} will be thrown.
- *
+ *
* @param pair
* the key pair to associate with this {@code Signer}.
* @throws InvalidParameterException
@@ -115,7 +101,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and the caller does
* not have permission to invoke this method.
- * @since Android 1.0
*/
public final void setKeyPair(KeyPair pair)
throws InvalidParameterException, KeyException {
@@ -148,10 +133,10 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code Signer} including its name and its scope if present.
- *
+ *
* @return a printable representation for this {@code Signer}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
String s = "[Signer]" + getName(); //$NON-NLS-1$
if (getScope() != null) {
diff --git a/security/src/main/java/java/security/Timestamp.java b/security/src/main/java/java/security/Timestamp.java
index 1d31e6f..5a2930a 100644
--- a/security/src/main/java/java/security/Timestamp.java
+++ b/security/src/main/java/java/security/Timestamp.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexander V. Astapchuk
-* @version $Revision$
-*/
-
package java.security;
import java.io.Serializable;
@@ -31,8 +26,6 @@
/**
* {@code Timestamp} represents a signed time stamp. {@code Timestamp} is
* immutable.
- *
- * @since Android 1.0
*/
public final class Timestamp implements Serializable {
@@ -48,7 +41,7 @@
/**
* Constructs a new instance of {@code Timestamp} with the specified {@code
* timestamp} and the given certificate path.
- *
+ *
* @param timestamp
* date and time.
* @param signerCertPath
@@ -56,7 +49,6 @@
* @throws NullPointerException
* if {@code timestamp} is {@code null} or if {@code
* signerCertPath} is {@code null}.
- * @since Android 1.0
*/
public Timestamp(Date timestamp, CertPath signerCertPath) {
if (timestamp == null) {
@@ -76,15 +68,15 @@
* otherwise. The given object is equal to this {@code Timestamp}, if it is
* an instance of {@code Timestamp}, the two timestamps have an equal date
* and time and their certificate paths are equal.
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* Timestamp}.
* @return {@code true} if the specified object is equal to this {@code
* Timestamp}, otherwise {@code false}.
* @see #hashCode
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
@@ -99,9 +91,8 @@
/**
* Returns the certificate path of this {@code Timestamp}.
- *
+ *
* @return the certificate path of this {@code Timestamp}.
- * @since Android 1.0
*/
public CertPath getSignerCertPath() {
return signerCertPath;
@@ -109,15 +100,11 @@
/**
* Returns the date and time of this {@code Timestamp}.
- *
+ *
* @return the date and time of this {@code Timestamp}.
- * @since Android 1.0
*/
public Date getTimestamp() {
- // BEGIN android-changed
- // copied from a newer version of harmony
return (Date) timestamp.clone();
- // END android-changed
}
/**
@@ -128,8 +115,8 @@
* @return the hash code value for this {@code Timestamp}.
* @see Object#equals(Object)
* @see Timestamp#equals(Object)
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
if (hash == 0) {
hash = timestamp.hashCode() ^ signerCertPath.hashCode();
@@ -140,15 +127,15 @@
/**
* Returns a string containing a concise, human-readable description of this
* {@code Timestamp}.
- *
+ *
* @return a printable representation for this {@code Timestamp}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- StringBuffer buf = new StringBuffer(256);
+ StringBuilder buf = new StringBuilder(256);
// Dump only the first certificate
buf.append("Timestamp [").append(timestamp).append(" certPath="); //$NON-NLS-1$ //$NON-NLS-2$
buf.append(signerCertPath.getCertificates().get(0)).append("]"); //$NON-NLS-1$
return buf.toString();
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/UnrecoverableEntryException.java b/security/src/main/java/java/security/UnrecoverableEntryException.java
index dc2981a..24ff54b 100644
--- a/security/src/main/java/java/security/UnrecoverableEntryException.java
+++ b/security/src/main/java/java/security/UnrecoverableEntryException.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
@@ -29,7 +24,6 @@
*
* @see KeyStore
* @see KeyStore.Entry
- * @since Android 1.0
*/
public class UnrecoverableEntryException extends GeneralSecurityException {
@@ -37,8 +31,6 @@
/**
* Constructs a new instance of {@code UnrecoverableEntryException}.
- *
- * @since Android 1.0
*/
public UnrecoverableEntryException() {
}
@@ -46,12 +38,11 @@
/**
* Constructs a new instance of {@code UnrecoverableEntryException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public UnrecoverableEntryException(String msg) {
super(msg);
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/UnrecoverableKeyException.java b/security/src/main/java/java/security/UnrecoverableKeyException.java
index e4b399b..3840e6b 100644
--- a/security/src/main/java/java/security/UnrecoverableKeyException.java
+++ b/security/src/main/java/java/security/UnrecoverableKeyException.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security;
/**
@@ -27,7 +22,6 @@
* from a {@code KeyStore}.
*
* @see KeyStore
- * @since Android 1.0
*/
public class UnrecoverableKeyException extends GeneralSecurityException {
@@ -36,10 +30,9 @@
/**
* Constructs a new instance of {@code UnrecoverableKeyException} with the
* given message.
- *
+ *
* @param msg
* the detail message for this exception
- * @since Android 1.0
*/
public UnrecoverableKeyException(String msg) {
super(msg);
@@ -47,8 +40,6 @@
/**
* Constructs a new instance of {@code UnrecoverableKeyException}.
- *
- * @since Android 1.0
*/
public UnrecoverableKeyException() {
}
diff --git a/security/src/main/java/java/security/UnresolvedPermission.java b/security/src/main/java/java/security/UnresolvedPermission.java
index 6570de4..bf99a40 100644
--- a/security/src/main/java/java/security/UnresolvedPermission.java
+++ b/security/src/main/java/java/security/UnresolvedPermission.java
@@ -15,27 +15,18 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InvalidObjectException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.ObjectStreamField;
import java.io.Serializable;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.harmony.security.fortress.PolicyUtils;
import org.apache.harmony.security.internal.nls.Messages;
@@ -46,24 +37,17 @@
* Policy}. {@code UnresolvedPermission}s contain all information to be replaced
* by a concrete typed {@code Permission} right before the access checks are
* performed.
- *
- * @since Android 1.0
*/
public final class UnresolvedPermission extends Permission
implements Serializable {
private static final long serialVersionUID = -4821973115467008846L;
- private static final ObjectStreamField serialPersistentFields[] = {
- new ObjectStreamField("type", String.class), //$NON-NLS-1$
- new ObjectStreamField("name", String.class), //$NON-NLS-1$
- new ObjectStreamField("actions", String.class), }; //$NON-NLS-1$
-
- // Target name
- private transient String targetName;
-
- //Target actions
- private transient String targetActions;
+ private String type;
+
+ private String name;
+
+ private String actions;
// The signer certificates
private transient Certificate[] targetCerts;
@@ -75,7 +59,7 @@
* Constructs a new instance of {@code UnresolvedPermission}. The supplied
* parameters are used when this instance is resolved to the concrete
* {@code Permission}.
- *
+ *
* @param type
* the fully qualified class name of the permission this class is
* resolved to.
@@ -90,26 +74,17 @@
* maybe {@code null}.
* @throws NullPointerException
* if type is {@code null}.
- * @since Android 1.0
*/
public UnresolvedPermission(String type, String name, String actions,
Certificate[] certs) {
super(type);
checkType(type);
- targetName = name;
- targetActions = actions;
- if (certs != null && certs.length != 0) {
- //TODO filter non-signer certificates ???
- List tmp = new ArrayList();
- for (int i = 0; i < certs.length; i++) {
- if (certs[i] != null) {
- tmp.add(certs[i]);
- }
- }
- if (tmp.size() != 0) {
- targetCerts = (Certificate[])tmp.toArray(
- new Certificate[tmp.size()]);
- }
+ this.type = type;
+ this.name = name;
+ this.actions = actions;
+ if (certs != null) {
+ this.targetCerts = new Certificate[certs.length];
+ System.arraycopy(certs, 0, targetCerts, 0, certs.length);
}
hash = 0;
}
@@ -136,52 +111,105 @@
* instance of {@code UnresolvedPermission}, the two {@code
* UnresolvedPermission}s must refer to the same type and must have the same
* name, the same actions and certificates.
- *
+ *
* @param obj
* object to be compared for equality with this {@code
* UnresolvedPermission}.
* @return {@code true} if the specified object is equal to this {@code
* UnresolvedPermission}, otherwise {@code false}.
- * @since Android 1.0
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof UnresolvedPermission) {
- UnresolvedPermission that = (UnresolvedPermission)obj;
+ UnresolvedPermission that = (UnresolvedPermission) obj;
if (getName().equals(that.getName())
- && (targetName == null ? that.targetName == null
- : targetName.equals(that.targetName))
- && (targetActions == null ? that.targetActions == null
- : targetActions.equals(that.targetActions))
- && (PolicyUtils.matchSubset(targetCerts, that.targetCerts)
- && PolicyUtils.matchSubset(that.targetCerts, targetCerts))) {
+ && (name == null ? that.name == null : name
+ .equals(that.name))
+ && (actions == null ? that.actions == null : actions
+ .equals(that.actions))
+ && equalsCertificates(this.targetCerts, that.targetCerts)) {
return true;
}
}
return false;
}
+ /*
+ * check whether given array of certificates are equivalent
+ */
+ private boolean equalsCertificates(Certificate[] certs1,
+ Certificate[] certs2) {
+ if (certs1 == null || certs2 == null) {
+ return certs1 == certs2;
+ }
+
+ int length = certs1.length;
+ if (length != certs2.length) {
+ return false;
+ }
+
+ if (length > 0) {
+ boolean found;
+ for (int i = 0; i < length; i++) {
+ // Skip the checking for null
+ if(certs1[i] == null){
+ continue;
+ }
+ found = false;
+ for (int j = 0; j < length; j++) {
+ if (certs1[i].equals(certs2[j])) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return false;
+ }
+ }
+
+ for (int i = 0; i < length; i++) {
+ if(certs2[i] == null){
+ continue;
+ }
+ found = false;
+ for (int j = 0; j < length; j++) {
+ if (certs2[i].equals(certs1[j])) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
/**
* Returns the hash code value for this {@code UnresolvedPermission}.
* Returns the same hash code for {@code UnresolvedPermission}s that are
* equal to each other as required by the general contract of
* {@link Object#hashCode}.
- *
+ *
* @return the hash code value for this {@code UnresolvedPermission}.
* @see Object#equals(Object)
* @see UnresolvedPermission#equals(Object)
- * @since Android 1.0
*/
+ @Override
public int hashCode() {
if (hash == 0) {
hash = getName().hashCode();
- if (targetName != null) {
- hash ^= targetName.hashCode();
+ if (name != null) {
+ hash ^= name.hashCode();
}
- if (targetActions != null) {
- hash ^= targetActions.hashCode();
+ if (actions != null) {
+ hash ^= actions.hashCode();
}
}
return hash;
@@ -191,10 +219,10 @@
* Returns an empty string since there are no actions allowed for {@code
* UnresolvedPermission}. The actions, specified in the constructor, are
* used when the concrete permission is resolved and created.
- *
+ *
* @return an empty string, indicating that there are no actions.
- * @since Android 1.0
*/
+ @Override
public String getActions() {
return ""; //$NON-NLS-1$
}
@@ -202,34 +230,31 @@
/**
* Returns the name of the permission this {@code UnresolvedPermission} is
* resolved to.
- *
+ *
* @return the name of the permission this {@code UnresolvedPermission} is
* resolved to.
- * @since Android 1.0
*/
public String getUnresolvedName() {
- return targetName;
+ return name;
}
/**
* Returns the actions of the permission this {@code UnresolvedPermission}
* is resolved to.
- *
+ *
* @return the actions of the permission this {@code UnresolvedPermission}
* is resolved to.
- * @since Android 1.0
*/
public String getUnresolvedActions() {
- return targetActions;
+ return actions;
}
/**
* Returns the fully qualified class name of the permission this {@code
* UnresolvedPermission} is resolved to.
- *
+ *
* @return the fully qualified class name of the permission this {@code
* UnresolvedPermission} is resolved to.
- * @since Android 1.0
*/
public String getUnresolvedType() {
return super.getName();
@@ -238,10 +263,9 @@
/**
* Returns the certificates of the permission this {@code
* UnresolvedPermission} is resolved to.
- *
+ *
* @return the certificates of the permission this {@code
* UnresolvedPermission} is resolved to.
- * @since Android 1.0
*/
public Certificate[] getUnresolvedCerts() {
if (targetCerts != null) {
@@ -261,13 +285,12 @@
* UnresolvedPermissions (if any) against the passed instance. Successfully
* resolved permissions (if any) are taken into account during further
* processing.
- * </p>
- *
+ *
* @param permission
* the permission to check.
* @return always {@code false}
- * @since Android 1.0
*/
+ @Override
public boolean implies(Permission permission) {
return false;
}
@@ -276,23 +299,23 @@
* Returns a string containing a concise, human-readable description of this
* {@code UnresolvedPermission} including its target name and its target
* actions.
- *
+ *
* @return a printable representation for this {@code UnresolvedPermission}.
- * @since Android 1.0
*/
+ @Override
public String toString() {
- return "(unresolved " + getName() + " " + targetName + " " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + targetActions + ")"; //$NON-NLS-1$
+ return "(unresolved " + type + " " + name + " " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ + actions + ")"; //$NON-NLS-1$
}
/**
* Returns a new {@code PermissionCollection} for holding {@code
* UnresolvedPermission} objects.
- *
+ *
* @return a new PermissionCollection for holding {@code
* UnresolvedPermission} objects.
- * @since Android 1.0
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new UnresolvedPermissionCollection();
}
@@ -306,16 +329,12 @@
* per {@code getUnresolvedCerts()}) among the passed collection of signers.
* If it does, a zero, one, and/or two-argument constructor is tried to
* instantiate a new permission, which is then returned.
- * </p>
* <p>
* If an appropriate constructor is not available or the class is improperly
* signed, {@code null} is returned.
- * </p>
- *
+ *
* @param targetType
* - a target class instance, must not be {@code null}
- * @param signers
- * - actual signers of the targetType
* @return resolved permission or null
*/
Permission resolve(Class targetType) {
@@ -323,8 +342,8 @@
if (PolicyUtils.matchSubset(targetCerts, targetType.getSigners())) {
try {
return PolicyUtils.instantiatePermission(targetType,
- targetName,
- targetActions);
+ name,
+ actions);
} catch (Exception ignore) {
//TODO log warning?
}
@@ -333,8 +352,6 @@
}
/**
- * @com.intel.drl.spec_ref
- *
* Outputs {@code type},{@code name},{@code actions}
* fields via default mechanism; next manually writes certificates in the
* following format: <br>
@@ -353,11 +370,7 @@
* @see <a href="http://java.sun.com/j2se/1.5.0/docs/api/serialized-form.html#java.security.UnresolvedPermission">Java Spec</a>
*/
private void writeObject(ObjectOutputStream out) throws IOException {
- ObjectOutputStream.PutField fields = out.putFields();
- fields.put("type", getUnresolvedType()); //$NON-NLS-1$
- fields.put("name", getUnresolvedName()); //$NON-NLS-1$
- fields.put("actions", getUnresolvedActions()); //$NON-NLS-1$
- out.writeFields();
+ out.defaultWriteObject();
if (targetCerts == null) {
out.writeInt(0);
} else {
@@ -378,19 +391,12 @@
}
/**
- * @com.intel.drl.spec_ref
- *
* Reads the object from stream and checks target type for validity.
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
- checkType(getUnresolvedType());
- ObjectInputStream.GetField fields = in.readFields();
- if (!getUnresolvedType().equals(fields.get("type", null))) { //$NON-NLS-1$
- throw new InvalidObjectException(Messages.getString("security.31")); //$NON-NLS-1$
- }
- targetName = (String)fields.get("name", null); //$NON-NLS-1$
- targetActions = (String)fields.get("actions", null); //$NON-NLS-1$
+ in.defaultReadObject();
+ checkType(getUnresolvedType());
int certNumber = in.readInt();
if (certNumber != 0) {
targetCerts = new Certificate[certNumber];
diff --git a/security/src/main/java/java/security/UnresolvedPermissionCollection.java b/security/src/main/java/java/security/UnresolvedPermissionCollection.java
index a43a54f..3a6ba92 100644
--- a/security/src/main/java/java/security/UnresolvedPermissionCollection.java
+++ b/security/src/main/java/java/security/UnresolvedPermissionCollection.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Alexey V. Varlamov
-* @version $Revision$
-*/
-
package java.security;
import java.io.IOException;
@@ -66,7 +61,6 @@
* @throws IllegalArgumentException
* if {@code permission} is {@code null} or not an {@code
* UnresolvedPermission}.
- * @since Android 1.0
*/
public void add(Permission permission) {
if (isReadOnly()) {
@@ -101,7 +95,6 @@
*
* @return always {@code false}
* @see UnresolvedPermission#implies(Permission).
- * @since Android 1.0
*/
public boolean implies(Permission permission) {
return false;
@@ -159,15 +152,14 @@
}
/**
- * @com.intel.drl.spec_ref
- *
* Output fields via default mechanism.
*/
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
Hashtable permissions = new Hashtable();
- for (Iterator iter = klasses.keySet().iterator(); iter.hasNext();) {
- String key = (String)iter.next();
- permissions.put(key, new Vector(((Collection)klasses.get(key))));
+ for (Iterator iter = klasses.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String key = (String) entry.getKey();
+ permissions.put(key, new Vector(((Collection) entry.getValue())));
}
ObjectOutputStream.PutField fields = out.putFields();
fields.put("permissions", permissions); //$NON-NLS-1$
@@ -175,8 +167,6 @@
}
/**
- * @com.intel.drl.spec_ref
- *
* Reads the object from stream and checks elements grouping for validity.
*/
private void readObject(java.io.ObjectInputStream in) throws IOException,
@@ -185,20 +175,23 @@
Map permissions = (Map)fields.get("permissions", null); //$NON-NLS-1$
klasses = new HashMap();
synchronized (klasses) {
- for (Iterator iter = permissions.keySet().iterator(); iter
- .hasNext();) {
- String key = (String)iter.next();
- Collection values = (Collection)permissions.get(key);
- for (Iterator iterator = values.iterator(); iterator.hasNext();) {
- UnresolvedPermission element = (UnresolvedPermission)iterator
- .next();
- if (!element.getName().equals(key)) {
- throw new InvalidObjectException(
- Messages.getString("security.22")); //$NON-NLS-1$
- }
- }
- klasses.put(key, new HashSet(values));
- }
+ for (Iterator iter = permissions.entrySet().iterator(); iter
+ .hasNext();) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String key = (String) entry.getKey();
+ Collection values = (Collection) entry.getValue();
+
+ for (Iterator iterator = values.iterator(); iterator.hasNext();) {
+ UnresolvedPermission element =
+ (UnresolvedPermission) iterator.next();
+
+ if (!element.getName().equals(key)) {
+ throw new InvalidObjectException(
+ Messages.getString("security.22")); //$NON-NLS-1$
+ }
+ }
+ klasses.put(key, new HashSet(values));
+ }
}
}
}
\ No newline at end of file
diff --git a/security/src/main/java/java/security/acl/Acl.java b/security/src/main/java/java/security/acl/Acl.java
index 35c92fc..88dd9f0 100644
--- a/security/src/main/java/java/security/acl/Acl.java
+++ b/security/src/main/java/java/security/acl/Acl.java
@@ -24,17 +24,15 @@
* The <i>Access Control List</i> (<b>ACL</b>) interface definition.
* <p>
* An ACL is a set of {@link AclEntry} objects.
- * </p>
* <p>
* An {@code AclEntry} is a list of {@link Permission}s that are granted
* (<i>positive</i>) or denied
* (<i>negative</i>) to a {@link Principal}.
- * </p>
* <p>
- * An {@code Acl} has a list of owners ({@link Owner}) which are principals as well {@code
- * Principal}. Only those principals which are the {@code Acl}'s owners are allowed to modify the {@code
+ * An {@code Acl} has a list of owners ({@link Owner}) which are principals as
+ * well {@code Principal}. Only those principals which are the {@code Acl}'s
+ * owners are allowed to modify the {@code
* Acl}.
- * </p>
* <p>
* The <i>ACL</i> has to conform to the following rules:
* <ul>
@@ -49,9 +47,6 @@
* <li>If there is no {@code AclEntry} associated with a specific {@code
* Principal}, then it is interpreted as an empty list of permissions.</li>
* </ul>
- * </p>
- *
- * @since Android 1.0
*/
public interface Acl extends Owner {
@@ -65,7 +60,6 @@
* @throws NotOwnerException
* if the invoking {@code Principal} is not an owner of this
* <i>ACL</i>.
- * @since Android 1.0
*/
void setName(Principal caller, String name) throws NotOwnerException;
@@ -73,7 +67,6 @@
* Returns the name of this <i>ACL</i> instance.
*
* @return the name of this <i>ACL</i> instance.
- * @since Android 1.0
*/
String getName();
@@ -82,18 +75,16 @@
* <p>
* If the <i>ACL</i> already has an {@code AclEntry} of the same type (<i>
* positive</i> or <i>negative</i>) and principal, then the new entry is not added.
- * </p>
- *
+ *
* @param caller
* the invoking {@code Principal}.
* @param entry
* the ACL entry to add.
- * @return {@code true} if the entry is added, {@code false} if there is already an entry of
- * the same type for the same principal
+ * @return {@code true} if the entry is added, {@code false} if there is
+ * already an entry of the same type for the same principal
* @throws NotOwnerException
* if the invoking {@code Principal} is not an owner of this
* <i>ACL</i>.
- * @since Android 1.0
*/
boolean addEntry(Principal caller, AclEntry entry) throws NotOwnerException;
@@ -104,12 +95,11 @@
* the invoking {@code Principal}.
* @param entry
* the ACL entry to remove.
- * @return {@code true} if the entry is removed, {@code false} if the entry is not in this
- * <i>ACL</i>.
+ * @return {@code true} if the entry is removed, {@code false} if the entry
+ * is not in this <i>ACL</i>.
* @throws NotOwnerException
* if the invoking {@code Principal} is not an owner of this
* <i>ACL</i>.
- * @since Android 1.0
*/
boolean removeEntry(Principal caller, AclEntry entry)
throws NotOwnerException;
@@ -120,7 +110,6 @@
* <p>
* If the specified principal has no entry in this ACL, an empty set is
* returned.
- * </p>
* <p>
* The allowed permissions are collected according to the following rules:
* <ul>
@@ -136,12 +125,10 @@
* permissions override the group's negative permissions and the negative
* individual permissions override the grpup's positive permissions.</li>
* </ul>
- * </p>
- *
+ *
* @param user
* the principal to get the allowed permissions for.
* @return the set of allowed permissions for the specified principal.
- * @since Android 1.0
*/
Enumeration<Permission> getPermissions(Principal user);
@@ -151,7 +138,6 @@
*
* @return an {@code Enumeration} of the {@code AclEntry} of this
* <i>ACL</i>.
- * @since Android 1.0
*/
Enumeration<AclEntry> entries();
@@ -161,15 +147,14 @@
* <p>
* The list of granted permissions is determined according to the rules
* specified by {@code getPermissions}.
- * </p>
- *
+ *
* @param principal
* the principal the check the permissions for.
* @param permission
* the permission to check for the principal.
- * @return {@code true} if the principal is granted the permission, otherwise {@code false}.
+ * @return {@code true} if the principal is granted the permission,
+ * otherwise {@code false}.
* @see #getPermissions(Principal)
- * @since Android 1.0
*/
boolean checkPermission(Principal principal, Permission permission);
@@ -177,7 +162,6 @@
* Returns the string representation of this ACL.
*
* @return the string representation of this ACL.
- * @since Android 1.0
*/
String toString();
}
diff --git a/security/src/main/java/java/security/acl/AclEntry.java b/security/src/main/java/java/security/acl/AclEntry.java
index 7a5b722..fe2fb3a 100644
--- a/security/src/main/java/java/security/acl/AclEntry.java
+++ b/security/src/main/java/java/security/acl/AclEntry.java
@@ -25,9 +25,6 @@
* <p>
* An {@code AclEntry} is a list of the {@link Permission}s that are
* granted (<i>positive</i>) or denied (<i>negative</i>) to a {@link Principal}.
- * </p>
- *
- * @since Android 1.0
*/
public interface AclEntry extends Cloneable {
@@ -35,13 +32,11 @@
* Set the principal for this ACL entry.
* <p>
* The principal for an ACL entry can only be set once.
- * </p>
- *
+ *
* @param user
* the principal for this ACL entry.
* @return {@code true} on success, {@code false} if there is a principal already set for
* this entry.
- * @since Android 1.0
*/
boolean setPrincipal(Principal user);
@@ -49,7 +44,6 @@
* Returns the principal of this ACL entry.
*
* @return the principal of this ACL entry, or null if none is set.
- * @since Android 1.0
*/
Principal getPrincipal();
@@ -58,13 +52,9 @@
* <p>
* The permissions in this ACL entry will be denied to the principal
* associated with this entry.
- * </p>
* <p>
* Note: An ACL entry is <i>positive</i> by default and can only become
* <i>negative</i> by calling this method.
- * </p>
- *
- * @since Android 1.0
*/
void setNegativePermissions();
@@ -72,7 +62,6 @@
* Returns whether this ACL entry is <i>negative</i>.
*
* @return {@code true} if this ACL entry is negative, {@code false} if it's positive.
- * @since Android 1.0
*/
boolean isNegative();
@@ -83,7 +72,6 @@
* the permission to be added.
* @return {@code true} if the specified permission is added, {@code false} if the
* permission was already in this entry.
- * @since Android 1.0
*/
boolean addPermission(Permission permission);
@@ -94,7 +82,6 @@
* the permission to be removed.
* @return {@code true} if the permission is removed, {@code false} if the permission was
* not in this entry.
- * @since Android 1.0
*/
boolean removePermission(Permission permission);
@@ -104,7 +91,6 @@
* @param permission
* the permission to check.
* @return {@code true} if the permission is in this entry, otherwise {@code false}.
- * @since Android 1.0
*/
boolean checkPermission(Permission permission);
@@ -112,7 +98,6 @@
* Returns the list of permissions of this ACL entry.
*
* @return the list of permissions of this ACL entry,
- * @since Android 1.0
*/
Enumeration<Permission> permissions();
@@ -120,7 +105,6 @@
* Returns the string representation of this ACL entry.
*
* @return the string representation of this ACL entry.
- * @since Android 1.0
*/
String toString();
@@ -128,7 +112,6 @@
* Clones this ACL entry instance.
*
* @return a copy of this entry.
- * @since Android 1.0
*/
Object clone();
diff --git a/security/src/main/java/java/security/acl/AclNotFoundException.java b/security/src/main/java/java/security/acl/AclNotFoundException.java
index c8d4208..59b9045 100644
--- a/security/src/main/java/java/security/acl/AclNotFoundException.java
+++ b/security/src/main/java/java/security/acl/AclNotFoundException.java
@@ -20,18 +20,13 @@
/**
* The exception, that is thrown when a reference to a non-existent <i>Access
* Control List</i> (ACL) is made.
- *
- * @since Android 1.0
*/
-
public class AclNotFoundException extends Exception {
private static final long serialVersionUID = 5684295034092681791L;
/**
* Creates a new {@code AclNotFoundException}.
- *
- * @since Android 1.0
*/
public AclNotFoundException() {
diff --git a/security/src/main/java/java/security/acl/Group.java b/security/src/main/java/java/security/acl/Group.java
index 16898e6..7452181 100644
--- a/security/src/main/java/java/security/acl/Group.java
+++ b/security/src/main/java/java/security/acl/Group.java
@@ -24,8 +24,6 @@
* A {@code Principal} that represents a group of principals.
*
* @see Principal
- *
- * @since Android 1.0
*/
public interface Group extends Principal {
@@ -35,7 +33,6 @@
* @param user
* the member to add.
* @return {@code true} if the member was added, {@code false} if it was already a member.
- * @since Android 1.0
*/
boolean addMember(Principal user);
@@ -45,7 +42,6 @@
* @param user
* the member to remove.
* @return {@code true} if the member was removed, {@code false} if it was not a member.
- * @since Android 1.0
*/
boolean removeMember(Principal user);
@@ -55,7 +51,6 @@
* @param member
* the principal to check.
* @return {@code true} if the principal is a member, otherwise {@code false}.
- * @since Android 1.0
*/
boolean isMember(Principal member);
@@ -63,7 +58,6 @@
* Returns the members of this group.
*
* @return the members of this group.
- * @since Android 1.0
*/
Enumeration<? extends Principal> members();
diff --git a/security/src/main/java/java/security/acl/LastOwnerException.java b/security/src/main/java/java/security/acl/LastOwnerException.java
index 11c235f..f947f22 100644
--- a/security/src/main/java/java/security/acl/LastOwnerException.java
+++ b/security/src/main/java/java/security/acl/LastOwnerException.java
@@ -18,12 +18,10 @@
package java.security.acl;
/**
- * The exception that is thrown when an attempt is made to remove the
+ * The exception that is thrown when an attempt is made to remove the
* the last {@code Owner} from an {@code Owner}.
- *
+ *
* @see Owner
- *
- * @since Android 1.0
*/
public class LastOwnerException extends Exception {
@@ -31,9 +29,7 @@
/**
* Creates a new {@code LastOwnerException}.
- *
- * @since Android 1.0
*/
public LastOwnerException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/acl/NotOwnerException.java b/security/src/main/java/java/security/acl/NotOwnerException.java
index 081bdea..c7de8c9 100644
--- a/security/src/main/java/java/security/acl/NotOwnerException.java
+++ b/security/src/main/java/java/security/acl/NotOwnerException.java
@@ -19,13 +19,11 @@
/**
* The exception that is thrown when an action that requires ownership is
- * attempted by a principal that is not an owner of the object for which
- * ownership is required.
+ * attempted by a principal that is not an owner of the object for which
+ * ownership is required.
*
* @see Acl
* @see Owner
- *
- * @since Android 1.0
*/
public class NotOwnerException extends Exception {
@@ -33,9 +31,7 @@
/**
* Creates a new {@code NotOwnerException}.
- *
- * @since Android 1.0
*/
public NotOwnerException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/acl/Owner.java b/security/src/main/java/java/security/acl/Owner.java
index 335dc84..c392e2f 100644
--- a/security/src/main/java/java/security/acl/Owner.java
+++ b/security/src/main/java/java/security/acl/Owner.java
@@ -24,7 +24,6 @@
*
* @see Acl
* @see Principal
- * @since Android 1.0
*/
public interface Owner {
@@ -38,7 +37,6 @@
* @return {@code true} if the owner was added, {@code false} if it was already an owner.
* @throws NotOwnerException
* if the invoking principal is not an owner.
- * @since Android 1.0
*/
boolean addOwner(Principal caller, Principal owner)
throws NotOwnerException;
@@ -56,7 +54,6 @@
* @throws LastOwnerException
* if the owner to be removed is the last owner and hence removing it
* would make this object owner-less.
- * @since Android 1.0
*/
boolean deleteOwner(Principal caller, Principal owner)
throws NotOwnerException, LastOwnerException;
@@ -67,7 +64,6 @@
* @param owner
* the principal to check.
* @return {@code true} if the specified principal is an owner, otherwise {@code false}.
- * @since Android 1.0
*/
boolean isOwner(Principal owner);
}
diff --git a/security/src/main/java/java/security/acl/Permission.java b/security/src/main/java/java/security/acl/Permission.java
index 0d6e22c..f2ee251 100644
--- a/security/src/main/java/java/security/acl/Permission.java
+++ b/security/src/main/java/java/security/acl/Permission.java
@@ -22,9 +22,6 @@
* <p>
* It can be granted or denied to a {@link java.security.Principal Principal}
* using an {@link Acl}.
- * </p>
- *
- * @since Android 1.0
*/
public interface Permission {
@@ -36,7 +33,6 @@
* the permission object to compare to this permission.
* @return true if the specified permission object is equal to this, false
* if not.
- * @since Android 1.0
*/
boolean equals(Object another);
@@ -44,7 +40,6 @@
* Returns the string representation of this permission.
*
* @return the string representation of this permission.
- * @since Android 1.0
*/
String toString();
}
diff --git a/security/src/main/java/java/security/cert/CRL.java b/security/src/main/java/java/security/cert/CRL.java
index b0f3e30..8153853 100644
--- a/security/src/main/java/java/security/cert/CRL.java
+++ b/security/src/main/java/java/security/cert/CRL.java
@@ -23,7 +23,6 @@
* expired and consequently has become invalid.
*
* @see CertificateFactory
- * @since Android 1.0
*/
public abstract class CRL {
// The CRL type
@@ -31,10 +30,9 @@
/**
* Creates a new certificate revocation list of the specified type.
- *
+ *
* @param type
* the type for the CRL.
- * @since Android 1.0
*/
protected CRL(String type) {
this.type = type;
@@ -42,9 +40,8 @@
/**
* Returns the type of this CRL.
- *
+ *
* @return the type of this CRL.
- * @since Android 1.0
*/
public final String getType() {
return type;
@@ -52,20 +49,18 @@
/**
* Returns whether the specified certificate is revoked by this CRL.
- *
+ *
* @param cert
* the certificate to check.
* @return {@code true} if the certificate is revoked by this CRL, otherwise
* {@code false}.
- * @since Android 1.0
*/
public abstract boolean isRevoked(Certificate cert);
/**
* Returns the string representation of this instance.
- *
+ *
* @return the string representation of this instance.
- * @since Android 1.0
*/
public abstract String toString();
}
diff --git a/security/src/main/java/java/security/cert/CRLException.java b/security/src/main/java/java/security/cert/CRLException.java
index 625d7d3..01e2071 100644
--- a/security/src/main/java/java/security/cert/CRLException.java
+++ b/security/src/main/java/java/security/cert/CRLException.java
@@ -15,19 +15,12 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security.cert;
import java.security.GeneralSecurityException;
/**
* The exception that is thrown if errors occur during handling of {@code CRL}s.
- *
- * @since Android 1.0
*/
public class CRLException extends GeneralSecurityException {
@@ -38,7 +31,6 @@
*
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public CRLException(String msg) {
super(msg);
@@ -46,8 +38,6 @@
/**
* Creates a new {@code CRLException}.
- *
- * @since Android 1.0
*/
public CRLException() {
}
@@ -59,7 +49,6 @@
* the detail message for this exception.
* @param cause
* the cause for this exception.
- * @since Android 1.0
*/
public CRLException(String message, Throwable cause) {
super(message, cause);
@@ -70,7 +59,6 @@
*
* @param cause
* the cause for this exception.
- * @since Android 1.0
*/
public CRLException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/cert/CRLSelector.java b/security/src/main/java/java/security/cert/CRLSelector.java
index ee2d39e..5b14446 100644
--- a/security/src/main/java/java/security/cert/CRLSelector.java
+++ b/security/src/main/java/java/security/cert/CRLSelector.java
@@ -23,11 +23,9 @@
* <p>
* The implementations of this interface are typically used to define the
* criteria for selecting {@code CRL}s from a {@code CertStore}.
- * </p>
*
* @see CertStore
* @see CRL
- * @since Android 1.0
*/
public interface CRLSelector extends Cloneable {
@@ -35,7 +33,6 @@
* Clones this {@code CRLSelector} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone();
@@ -47,7 +44,6 @@
* the CRL to be evaluated.
* @return {@code true} if the CRL matches the criteria, {@code false}
* otherwise.
- * @since Android 1.0
*/
public boolean match(CRL crl);
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPath.java b/security/src/main/java/java/security/cert/CertPath.java
index 2874a4d..e9d049b 100644
--- a/security/src/main/java/java/security/cert/CertPath.java
+++ b/security/src/main/java/java/security/cert/CertPath.java
@@ -33,16 +33,12 @@
* <p>
* A {@code CertPath} can be represented as a byte array in at least one
* supported encoding scheme (i.e. PkiPath or PKCS7) when serialized.
- * </p>
* <p>
* When a {@code List} of the certificates is obtained it must be immutable.
- * </p>
* <p>
* A {@code CertPath} must be thread-safe without requiring coordinated access.
- * </p>
- *
+ *
* @see Certificate
- * @since Android 1.0
*/
public abstract class CertPath implements Serializable {
@@ -53,10 +49,9 @@
/**
* Creates a new {@code CertPath} instance for the specified certificate
* type.
- *
+ *
* @param type
* the certificate type.
- * @since Android 1.0
*/
protected CertPath(String type) {
this.type = type;
@@ -64,9 +59,8 @@
/**
* Returns the type of {@code Certificate} in this instance.
- *
+ *
* @return the certificate type.
- * @since Android 1.0
*/
public String getType() {
return type;
@@ -76,13 +70,11 @@
* Returns {@code true} if {@code Certificate}s in the list are the same
* type and the lists are equal (and by implication the certificates
* contained within are the same).
- *
+ *
* @param other
* {@code CertPath} to be compared for equality.
* @return {@code true} if the object are equal, {@code false} otherwise.
- * @since Android 1.0
*/
- @Override
public boolean equals(Object other) {
if (this == other) {
return true;
@@ -99,14 +91,14 @@
}
/**
- * Overrides {@code Object.hashCode()}. The function is defined as follows: <br>
+ * Overrides {@code Object.hashCode()}. The function is defined as follows:
+ * <pre>
* {@code hashCode = 31 * path.getType().hashCode() +
- * path.getCertificates().hashCode();}</br> </p>
- *
+ * path.getCertificates().hashCode();}
+ * </pre>
+ *
* @return the hash code for this instance.
- * @since Android 1.0
*/
- @Override
public int hashCode() {
int hash = getType().hashCode();
hash = hash*31 + getCertificates().hashCode();
@@ -115,13 +107,13 @@
/**
* Returns a {@code String} representation of this {@code CertPath}
- * instance.
- *
+ * instance. It is the result of calling {@code toString} on all {@code
+ * Certificate}s in the {@code List}.
+ *
* @return a string representation of this instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb = new StringBuffer(getType());
+ StringBuilder sb = new StringBuilder(getType());
sb.append(" Cert Path, len="); //$NON-NLS-1$
sb.append(getCertificates().size());
sb.append(": [\n"); //$NON-NLS-1$
@@ -144,7 +136,6 @@
* in the {@code CertPath}.
*
* @return a list of {@code Certificate}s in the {@code CertPath}.
- * @since Android 1.0
*/
public abstract List<? extends Certificate> getCertificates();
@@ -154,7 +145,6 @@
* @return default encoding of the {@code CertPath}.
* @throws CertificateEncodingException
* if the encoding fails.
- * @since Android 1.0
*/
public abstract byte[] getEncoded()
throws CertificateEncodingException;
@@ -167,7 +157,6 @@
* @return default encoding of the {@code CertPath}.
* @throws CertificateEncodingException
* if the encoding fails.
- * @since Android 1.0
*/
public abstract byte[] getEncoded(String encoding)
throws CertificateEncodingException;
@@ -177,17 +166,15 @@
* representation of the certificate path.
*
* @return {@code Iterator} over supported encodings (as {@code String}s).
- * @since Android 1.0
*/
public abstract Iterator<String> getEncodings();
/**
* Returns an alternate object to be serialized.
- *
+ *
* @return an alternate object to be serialized.
* @throws ObjectStreamException
* if the creation of the alternate object fails.
- * @since Android 1.0
*/
protected Object writeReplace() throws ObjectStreamException {
try {
@@ -201,8 +188,6 @@
/**
* The alternate {@code Serializable} class to be used for serialization and
* deserialization on {@code CertPath} objects.
- *
- * @since Android 1.0
*/
protected static class CertPathRep implements Serializable {
@@ -222,12 +207,11 @@
/**
* Creates a new {@code CertPathRep} instance with the specified type
* and encoded data.
- *
+ *
* @param type
* the certificate type.
* @param data
* the encoded data.
- * @since Android 1.0
*/
protected CertPathRep(String type, byte[] data) {
this.type = type;
@@ -237,11 +221,10 @@
/**
* Deserializes a {@code CertPath} from a serialized {@code CertPathRep}
* object.
- *
+ *
* @return the deserialized {@code CertPath}.
* @throws ObjectStreamException
* if deserialization fails.
- * @since Android 1.0
*/
protected Object readResolve() throws ObjectStreamException {
try {
diff --git a/security/src/main/java/java/security/cert/CertPathBuilder.java b/security/src/main/java/java/security/cert/CertPathBuilder.java
index 47eac13..8daa741 100644
--- a/security/src/main/java/java/security/cert/CertPathBuilder.java
+++ b/security/src/main/java/java/security/cert/CertPathBuilder.java
@@ -31,8 +31,6 @@
/**
* This class implements the functionality of a builder for an unverified
* <i>Certification Path</i>s from a specified certificate to a trust anchor.
- *
- * @since Android 1.0
*/
public class CertPathBuilder {
@@ -60,14 +58,13 @@
/**
* Creates a new {@code CertPathBuilder}.
- *
+ *
* @param builderSpi
* the implementation delegate.
* @param provider
* the provider.
* @param algorithm
* the desired algorithm available at the provider.
- * @since Android 1.0
*/
protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider,
String algorithm) {
@@ -78,9 +75,8 @@
/**
* Returns the algorithm name of this instance.
- *
+ *
* @return the algorithm name of this instance.
- * @since Android 1.0
*/
public final String getAlgorithm() {
return algorithm;
@@ -88,9 +84,8 @@
/**
* Returns the provider of this instance.
- *
+ *
* @return the provider of this instance.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -107,7 +102,6 @@
* if the algorithm is {@code null}.
* @throws NoSuchAlgorithmException
* if no installed provider can provide the algorithm.
- * @since Android 1.0
*/
public static CertPathBuilder getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -138,7 +132,6 @@
* if algorithm is {@code null}.
* @throws IllegalArgumentException
* if provider is {@code null} or empty.
- * @since Android 1.0
*/
public static CertPathBuilder getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
@@ -168,7 +161,6 @@
* if provider is {@code null}.
* @throws NullPointerException
* if algorithm is {@code null}.
- * @since Android 1.0
*/
public static CertPathBuilder getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
@@ -187,7 +179,7 @@
/**
* Builds a certification path with the specified algorithm parameters.
- *
+ *
* @param params
* the algorithm parameters.
* @return the built certification path.
@@ -197,7 +189,6 @@
* if the specified parameters cannot be used to build with this
* builder.
* @see CertPathBuilderResult
- * @since Android 1.0
*/
public final CertPathBuilderResult build(CertPathParameters params)
throws CertPathBuilderException, InvalidAlgorithmParameterException {
@@ -207,11 +198,10 @@
/**
* Returns the default {@code CertPathBuilder} type from the <i>Security
* Properties</i>.
- *
+ *
* @return the default {@code CertPathBuilder} type from the <i>Security
* Properties</i>, or the string "{@code PKIX}" if it cannot be
* determined.
- * @since Android 1.0
*/
public static final String getDefaultType() {
String defaultType = AccessController
@@ -222,4 +212,4 @@
});
return (defaultType != null ? defaultType : DEFAULTPROPERTY);
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPathBuilderException.java b/security/src/main/java/java/security/cert/CertPathBuilderException.java
index b957291..58a4a60 100644
--- a/security/src/main/java/java/security/cert/CertPathBuilderException.java
+++ b/security/src/main/java/java/security/cert/CertPathBuilderException.java
@@ -21,8 +21,6 @@
/**
* The exception that is thrown when a {@code CertPathBuilder} method fails.
- *
- * @since Android 1.0
*/
public class CertPathBuilderException extends GeneralSecurityException {
@@ -36,7 +34,6 @@
* the detail message for the exception
* @param cause
* why the building of the certification path failed.
- * @since Android 1.0
*/
public CertPathBuilderException(String msg, Throwable cause) {
super(msg, cause);
@@ -47,7 +44,6 @@
*
* @param cause
* why the building of the certification path failed.
- * @since Android 1.0
*/
public CertPathBuilderException(Throwable cause) {
super(cause);
@@ -59,7 +55,6 @@
*
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertPathBuilderException(String msg) {
super(msg);
@@ -67,9 +62,7 @@
/**
* Creates a new {@code CertPathBuilderException}.
- *
- * @since Android 1.0
*/
public CertPathBuilderException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPathBuilderResult.java b/security/src/main/java/java/security/cert/CertPathBuilderResult.java
index e56c4a0..36d99a1 100644
--- a/security/src/main/java/java/security/cert/CertPathBuilderResult.java
+++ b/security/src/main/java/java/security/cert/CertPathBuilderResult.java
@@ -20,8 +20,6 @@
/**
* The interface for results generated by
* {@link CertPathBuilder#build(CertPathParameters)}.
- *
- * @since Android 1.0
*/
public interface CertPathBuilderResult extends Cloneable {
@@ -29,7 +27,6 @@
* Clones this {@code CertPathBuilderResult} instance.
*
* @return the copy of this instance.
- * @since Android 1.0
*/
public Object clone();
@@ -37,7 +34,6 @@
* Returns the built {@code CertPath} instance. Never returns {@code null}.
*
* @return the built certificate path instance.
- * @since Android 1.0
*/
public CertPath getCertPath();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPathBuilderSpi.java b/security/src/main/java/java/security/cert/CertPathBuilderSpi.java
index 952f387..80ee0ef 100644
--- a/security/src/main/java/java/security/cert/CertPathBuilderSpi.java
+++ b/security/src/main/java/java/security/cert/CertPathBuilderSpi.java
@@ -22,15 +22,11 @@
/**
* The <i>Service Provider Interface</i> (<b>SPI</b>) for the {@code
* CertPathBuilder} class to be implemented by security providers.
- *
- * @since Android 1.0
*/
public abstract class CertPathBuilderSpi {
/**
* Creates a new {@code CertPathBuilderSpi} instance.
- *
- * @since Android 1.0
*/
public CertPathBuilderSpi() {
}
@@ -46,7 +42,6 @@
* @throws InvalidAlgorithmParameterException
* if the specified parameters cannot be used to build the path
* with this builder.
- * @since Android 1.0
*/
public abstract CertPathBuilderResult engineBuild(CertPathParameters params)
throws CertPathBuilderException, InvalidAlgorithmParameterException;
diff --git a/security/src/main/java/java/security/cert/CertPathParameters.java b/security/src/main/java/java/security/cert/CertPathParameters.java
index c99826f..e2cee18 100644
--- a/security/src/main/java/java/security/cert/CertPathParameters.java
+++ b/security/src/main/java/java/security/cert/CertPathParameters.java
@@ -22,8 +22,6 @@
* <p>
* This interface is for grouping purposes of {@code CertPath} parameter
* implementations.
- * </p>
- * @since Android 1.0
*/
public interface CertPathParameters extends Cloneable {
@@ -31,7 +29,6 @@
* Clones this {@code CertPathParameters} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPathValidator.java b/security/src/main/java/java/security/cert/CertPathValidator.java
index f95bd03..0d73280 100644
--- a/security/src/main/java/java/security/cert/CertPathValidator.java
+++ b/security/src/main/java/java/security/cert/CertPathValidator.java
@@ -32,8 +32,6 @@
* This class provides the functionality for validating certification paths
* (certificate chains) establishing a trust chain from a certificate to a trust
* anchor.
- *
- * @since Android 1.0
*/
public class CertPathValidator {
// Store CertPathValidator implementation service name
@@ -60,14 +58,13 @@
/**
* Creates a new {@code CertPathValidator} instance.
- *
+ *
* @param validatorSpi
* the implementation delegate.
* @param provider
* the security provider.
* @param algorithm
* the name of the algorithm.
- * @since Android 1.0
*/
protected CertPathValidator(CertPathValidatorSpi validatorSpi,
Provider provider, String algorithm) {
@@ -78,9 +75,8 @@
/**
* Returns the certification path algorithm name.
- *
+ *
* @return the certification path algorithm name.
- * @since Android 1.0
*/
public final String getAlgorithm() {
return algorithm;
@@ -88,9 +84,8 @@
/**
* Returns the security provider.
- *
+ *
* @return the provider.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -106,7 +101,6 @@
* if no installed provider provides the specified algorithm.
* @throws NullPointerException
* if algorithm is {@code null}.
- * @since Android 1.0
*/
public static CertPathValidator getInstance(String algorithm)
throws NoSuchAlgorithmException {
@@ -138,7 +132,6 @@
* if algorithm is {@code null}.
* @throws IllegalArgumentException
* if provider is {@code null} or empty.
- * @since Android 1.0
*/
public static CertPathValidator getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
@@ -169,7 +162,6 @@
* if provider is {@code null}.
* @throws NullPointerException
* if algorithm is {@code null}.
- * @since Android 1.0
*/
public static CertPathValidator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
@@ -203,7 +195,6 @@
* if the specified algorithm parameters cannot be used with
* this algorithm.
* @see CertPathValidatorResult
- * @since Android 1.0
*/
public final CertPathValidatorResult validate(CertPath certPath,
CertPathParameters params) throws CertPathValidatorException,
@@ -214,11 +205,10 @@
/**
* Returns the default {@code CertPathValidator} type from the <i>Security
* Properties</i>.
- *
+ *
* @return the default {@code CertPathValidator} type from the <i>Security
* Properties</i>, or the string {@code "PKIX"} if it cannot be
* determined.
- * @since Android 1.0
*/
public static final String getDefaultType() {
String defaultType = AccessController
@@ -229,4 +219,4 @@
});
return (defaultType != null ? defaultType : DEFAULTPROPERTY);
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPathValidatorException.java b/security/src/main/java/java/security/cert/CertPathValidatorException.java
index 072785c..4d2b69f 100644
--- a/security/src/main/java/java/security/cert/CertPathValidatorException.java
+++ b/security/src/main/java/java/security/cert/CertPathValidatorException.java
@@ -28,9 +28,6 @@
* A {@code CertPathValidatorException} may optionally include the certification
* path instance that failed the validation and the index of the failed
* certificate.
- * </p>
- *
- * @since Android 1.0
*/
public class CertPathValidatorException extends GeneralSecurityException {
@@ -65,7 +62,6 @@
* @throws IndexOutOfBoundsException
* if {@code certPath} is not {@code null} and index is not
* referencing an certificate in the certification path.
- * @since Android 1.0
*/
public CertPathValidatorException(String msg, Throwable cause,
CertPath certPath, int index) {
@@ -91,7 +87,6 @@
* the detail message for this exception.
* @param cause
* the cause why the path could not be validated.
- * @since Android 1.0
*/
public CertPathValidatorException(String msg, Throwable cause) {
super(msg, cause);
@@ -103,7 +98,6 @@
*
* @param cause
* the cause why the path could not be validated.
- * @since Android 1.0
*/
public CertPathValidatorException(Throwable cause) {
super(cause);
@@ -115,7 +109,6 @@
*
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public CertPathValidatorException(String msg) {
super(msg);
@@ -123,8 +116,6 @@
/**
* Creates a new {@code CertPathValidatorException}.
- *
- * @since Android 1.0
*/
public CertPathValidatorException() {
}
@@ -134,7 +125,6 @@
*
* @return the certification path that failed validation, or {@code null} if
* none was specified.
- * @since Android 1.0
*/
public CertPath getCertPath() {
return certPath;
@@ -145,9 +135,8 @@
*
* @return the index of the failed certificate in the certification path, or
* {@code -1} if none was specified.
- * @since Android 1.0
*/
public int getIndex() {
return index;
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPathValidatorResult.java b/security/src/main/java/java/security/cert/CertPathValidatorResult.java
index 42540e4..7fab21a 100644
--- a/security/src/main/java/java/security/cert/CertPathValidatorResult.java
+++ b/security/src/main/java/java/security/cert/CertPathValidatorResult.java
@@ -21,8 +21,6 @@
* The interface specification for certification path validation results.
* <p>
* This interface is for grouping purposes of validation result implementations.
- * </p>
- * @since Android 1.0
*/
public interface CertPathValidatorResult extends Cloneable {
@@ -30,7 +28,6 @@
* Clones this {@code CertPathValidatorResult} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertPathValidatorSpi.java b/security/src/main/java/java/security/cert/CertPathValidatorSpi.java
index 5573679..e14e8dd 100644
--- a/security/src/main/java/java/security/cert/CertPathValidatorSpi.java
+++ b/security/src/main/java/java/security/cert/CertPathValidatorSpi.java
@@ -22,15 +22,11 @@
/**
* The <i>Service Provider Interface</i> (<b>SPI</b>) for the {@code
* CertPathValidator} class to be implemented by security providers.
- *
- * @since Android 1.0
*/
public abstract class CertPathValidatorSpi {
/**
* Creates a new {@code CertPathValidatorSpi} instance.
- *
- * @since Android 1.0
*/
public CertPathValidatorSpi() {
}
@@ -38,7 +34,7 @@
/**
* Validates the {@code CertPath} with the algorithm of this {@code
* CertPathValidator} using the specified algorithm parameters.
- *
+ *
* @param certPath
* the certification path to be validated.
* @param params
@@ -51,10 +47,9 @@
* @throws InvalidAlgorithmParameterException
* if the specified algorithm parameters cannot be used with
* this algorithm.
- * @since Android 1.0
*/
public abstract CertPathValidatorResult engineValidate(CertPath certPath,
CertPathParameters params) throws CertPathValidatorException,
InvalidAlgorithmParameterException;
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertSelector.java b/security/src/main/java/java/security/cert/CertSelector.java
index 0316ad3..c490b22 100644
--- a/security/src/main/java/java/security/cert/CertSelector.java
+++ b/security/src/main/java/java/security/cert/CertSelector.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
-
package java.security.cert;
/**
@@ -28,11 +23,9 @@
* <p>
* The implementations of this interface are typically used to define the
* criteria for selecting {@code Certificate}s from a {@code CertStore}.
- * </p>
*
* @see CertStore
* @see Certificate
- * @since Android 1.0
*/
public interface CertSelector extends Cloneable {
@@ -40,7 +33,6 @@
* Clones this {@code CertSelector} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone();
@@ -52,7 +44,6 @@
* the certificate to be evaluated.
* @return {@code true} if the certificate matches the criteria, {@code
* false} otherwise.
- * @since Android 1.0
*/
public boolean match(Certificate cert);
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertStore.java b/security/src/main/java/java/security/cert/CertStore.java
index a5c8260..d0b7600 100644
--- a/security/src/main/java/java/security/cert/CertStore.java
+++ b/security/src/main/java/java/security/cert/CertStore.java
@@ -33,8 +33,6 @@
* This class provides the functionality to retrieve {@code Certificate}s and
* {@code CRL}s from a read-only repository. This repository may be very large
* and may store trusted as well as untrusted certificates.
- *
- * @since Android 1.0
*/
public class CertStore {
@@ -65,7 +63,7 @@
/**
* Creates a new {@code CertStore} instance.
- *
+ *
* @param storeSpi
* the implementation delegate.
* @param provider
@@ -74,7 +72,6 @@
* the certificate store type.
* @param params
* the certificate store parameters (may be {@code null}.
- * @since Android 1.0
*/
protected CertStore(CertStoreSpi storeSpi, Provider provider, String type,
CertStoreParameters params) {
@@ -101,7 +98,6 @@
* certificate store instance.
* @throws NullPointerException
* if the {@code type} is {@code null}.
- * @since Android 1.0
*/
public static CertStore getInstance(String type, CertStoreParameters params)
throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
@@ -147,7 +143,6 @@
* if provider is null of empty.
* @throws NullPointerException
* if {@code type} is {@code null}.
- * @since Android 1.0
*/
public static CertStore getInstance(String type,
CertStoreParameters params, String provider)
@@ -183,7 +178,6 @@
* if provider is {@code null}.
* @throws NullPointerException
* if {@code type} is {@code null}.
- * @since Android 1.0
*/
public static CertStore getInstance(String type,
CertStoreParameters params, Provider provider)
@@ -212,9 +206,8 @@
/**
* Returns the certificate store type.
- *
+ *
* @return the certificate store type.
- * @since Android 1.0
*/
public final String getType() {
return type;
@@ -222,9 +215,8 @@
/**
* Returns the security provider.
- *
+ *
* @return the security provider.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -233,10 +225,9 @@
/**
* Returns a copy of the certificate store parameters that were used to
* initialize this instance.
- *
+ *
* @return a copy of the certificate store parameters or {@code null} if
* none were specified.
- * @since Android 1.0
*/
public final CertStoreParameters getCertStoreParameters() {
if (certStoreParams == null) {
@@ -249,7 +240,7 @@
/**
* Returns the list of {@code Certificate}s for the specified {@code
* CertSelector} from this certificate store.
- *
+ *
* @param selector
* the selector containing the criteria to search for
* certificates in this certificate store.
@@ -257,7 +248,6 @@
* specified selector.
* @throws CertStoreException
* if error(s) occur.
- * @since Android 1.0
*/
public final Collection<? extends Certificate> getCertificates(CertSelector selector)
throws CertStoreException {
@@ -267,7 +257,7 @@
/**
* Returns the list of {@code CRL}s for the specified {@code CRLSelector}
* from this certificate store.
- *
+ *
* @param selector
* the selector containing the criteria to search for certificate
* revocation lists in this store.
@@ -275,7 +265,6 @@
* selector
* @throws CertStoreException
* if error(s) occur.
- * @since Android 1.0
*/
public final Collection<? extends CRL> getCRLs(CRLSelector selector)
throws CertStoreException {
@@ -285,12 +274,11 @@
/**
* Returns the default {@code CertStore} type from the <i>Security
* Properties</i>.
- *
+ *
* @return the default {@code CertStore} type from the <i>Security
* Properties</i>, or the string {@code "LDAP"} if it cannot be
* determined.
- * @since Android 1.0
- */
+ */
public static final String getDefaultType() {
String defaultType = AccessController
.doPrivileged(new java.security.PrivilegedAction<String>() {
diff --git a/security/src/main/java/java/security/cert/CertStoreException.java b/security/src/main/java/java/security/cert/CertStoreException.java
index 8351605..7f356b2 100644
--- a/security/src/main/java/java/security/cert/CertStoreException.java
+++ b/security/src/main/java/java/security/cert/CertStoreException.java
@@ -21,8 +21,6 @@
/**
* The exception that is thrown when an access to a {@code CertStore} fails.
- *
- * @since Android 1.0
*/
public class CertStoreException extends GeneralSecurityException {
@@ -36,7 +34,6 @@
* the detail message for this exception.
* @param cause
* the cause why the access to the certificate store failed.
- * @since Android 1.0
*/
public CertStoreException(String msg, Throwable cause) {
super(msg, cause);
@@ -47,7 +44,6 @@
*
* @param cause
* the cause why the access to the certificate store failed.
- * @since Android 1.0
*/
public CertStoreException(Throwable cause) {
super(cause);
@@ -58,7 +54,6 @@
*
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public CertStoreException(String msg) {
super(msg);
@@ -66,9 +61,7 @@
/**
* Creates a new {@code CertStoreException}.
- *
- * @since Android 1.0
*/
public CertStoreException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertStoreParameters.java b/security/src/main/java/java/security/cert/CertStoreParameters.java
index 566b2e2..06a1976 100644
--- a/security/src/main/java/java/security/cert/CertStoreParameters.java
+++ b/security/src/main/java/java/security/cert/CertStoreParameters.java
@@ -20,8 +20,6 @@
/**
* The marker interface specifying the parameters used to initialize a {@code
* CertStore} instance.
- *
- * @since Android 1.0
*/
public interface CertStoreParameters extends Cloneable {
@@ -29,7 +27,6 @@
* Clones this {@code CertStoreParameters} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/cert/CertStoreSpi.java b/security/src/main/java/java/security/cert/CertStoreSpi.java
index be680a7..cb38a31 100644
--- a/security/src/main/java/java/security/cert/CertStoreSpi.java
+++ b/security/src/main/java/java/security/cert/CertStoreSpi.java
@@ -23,8 +23,6 @@
/**
* The <i>Service Provider Interface</i> (<b>SPI</b>) definition for the {@code
* CertStore} class to be implemented by security providers.
- *
- * @since Android 1.0
*/
public abstract class CertStoreSpi {
@@ -36,7 +34,6 @@
* @throws InvalidAlgorithmParameterException
* if the specified initialization parameters cannot be used to
* initialize this instance.
- * @since Android 1.0
*/
public CertStoreSpi(CertStoreParameters params)
throws InvalidAlgorithmParameterException {
@@ -53,7 +50,6 @@
* specified selector.
* @throws CertStoreException
* if error(s) occur.
- * @since Android 1.0
*/
public abstract Collection<? extends Certificate> engineGetCertificates(CertSelector selector)
throws CertStoreException;
@@ -69,7 +65,6 @@
* selector
* @throws CertStoreException
* if error(s) occur.
- * @since Android 1.0
*/
public abstract Collection<? extends CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException;
diff --git a/security/src/main/java/java/security/cert/Certificate.java b/security/src/main/java/java/security/cert/Certificate.java
index 0543329..22cbe9c 100644
--- a/security/src/main/java/java/security/cert/Certificate.java
+++ b/security/src/main/java/java/security/cert/Certificate.java
@@ -35,8 +35,6 @@
* Abstract class to represent identity certificates. It represents a way to
* verify the binding of a Principal and its public key. Examples are X.509,
* PGP, and SDSI.
- *
- * @since Android 1.0
*/
public abstract class Certificate implements Serializable {
@@ -47,10 +45,9 @@
/**
* Creates a new {@code Certificate} with the specified type.
- *
+ *
* @param type
* the certificate type.
- * @since Android 1.0
*/
protected Certificate(String type) {
this.type = type;
@@ -58,9 +55,8 @@
/**
* Returns the certificate type.
- *
+ *
* @return the certificate type.
- * @since Android 1.0
*/
public final String getType() {
return type;
@@ -71,13 +67,12 @@
* represent the <em>same</em> object using a class specific comparison. The
* implementation in Object returns {@code true} only if the argument is the
* exact same object as the callee (==).
- *
+ *
* @param other
* the object to compare with this object.
* @return {@code true} if the object is the same as this object, {@code
* false} if it is different from this object.
* @see #hashCode
- * @since Android 1.0
*/
public boolean equals(Object other) {
// obj equal to itself
@@ -100,10 +95,9 @@
* Returns an integer hash code for the certificate. Any two objects which
* return {@code true} when passed to {@code equals} must return the same
* value for this method.
- *
+ *
* @return the certificate's hash
* @see #equals
- * @since Android 1.0
*/
public int hashCode() {
try {
@@ -120,17 +114,16 @@
/**
* Returns the encoded representation for this certificate.
- *
+ *
* @return the encoded representation for this certificate.
* @throws CertificateEncodingException
* if the encoding fails.
- * @since Android 1.0
*/
public abstract byte[] getEncoded() throws CertificateEncodingException;
/**
* Verifies that this certificate was signed with the given public key.
- *
+ *
* @param key
* PublicKey public key for which verification should be
* performed.
@@ -144,7 +137,6 @@
* if there is no default provider.
* @throws SignatureException
* if signature errors are detected.
- * @since Android 1.0
*/
public abstract void verify(PublicKey key)
throws CertificateException,
@@ -156,7 +148,7 @@
/**
* Verifies that this certificate was signed with the given public key. It
* Uses the signature algorithm given by the provider.
- *
+ *
* @param key
* PublicKey public key for which verification should be
* performed.
@@ -172,7 +164,6 @@
* if the specified provider does not exists.
* @exception SignatureException
* if signature errors are detected.
- * @since Android 1.0
*/
public abstract void verify(PublicKey key, String sigProvider)
throws CertificateException,
@@ -184,27 +175,24 @@
/**
* Returns a string containing a concise, human-readable description of the
* certificate.
- *
+ *
* @return a printable representation for the certificate.
- * @since Android 1.0
*/
public abstract String toString();
/**
* Returns the public key corresponding to this certificate.
- *
+ *
* @return the public key corresponding to this certificate.
- * @since Android 1.0
*/
public abstract PublicKey getPublicKey();
/**
* Returns an alternate object to be serialized.
- *
+ *
* @return the object to serialize.
* @throws ObjectStreamException
* if the creation of the alternate object fails.
- * @since Android 1.0
*/
protected Object writeReplace() throws ObjectStreamException {
try {
@@ -217,9 +205,7 @@
/**
* The alternate {@code Serializable} class to be used for serialization and
- * deserialization of {@code Certificate} objects.
- *
- * @since Android 1.0
+ * deserialization of {@code Certificate} objects.
*/
protected static class CertificateRep implements Serializable {
@@ -239,12 +225,11 @@
/**
* Creates a new {@code CertificateRep} instance with the specified
* certificate type and encoded data.
- *
+ *
* @param type
* the certificate type.
* @param data
* the encoded data.
- * @since Android 1.0
*/
protected CertificateRep(String type, byte[] data) {
this.type = type;
@@ -254,11 +239,10 @@
/**
* Deserializes a {@code Certificate} from a serialized {@code
* CertificateRep} object.
- *
+ *
* @return the deserialized {@code Certificate}.
* @throws ObjectStreamException
* if deserialization fails.
- * @since Android 1.0
*/
protected Object readResolve() throws ObjectStreamException {
try {
diff --git a/security/src/main/java/java/security/cert/CertificateEncodingException.java b/security/src/main/java/java/security/cert/CertificateEncodingException.java
index 188d084..c5532b9 100644
--- a/security/src/main/java/java/security/cert/CertificateEncodingException.java
+++ b/security/src/main/java/java/security/cert/CertificateEncodingException.java
@@ -20,8 +20,6 @@
/**
* The exception that is thrown when an error occurs while a {@code Certificate}
* is being encoded.
- *
- * @since Android 1.0
*/
public class CertificateEncodingException extends CertificateException {
@@ -33,7 +31,6 @@
*
* @param msg
* The detail message for the exception.
- * @since Android 1.0
*/
public CertificateEncodingException(String msg) {
super(msg);
@@ -41,8 +38,6 @@
/**
* Creates a new {@code CertificateEncodingException}.
- *
- * @since Android 1.0
*/
public CertificateEncodingException() {
}
@@ -55,7 +50,6 @@
* the detail message for the exception.
* @param cause
* the cause.
- * @since Android 1.0
*/
public CertificateEncodingException(String message, Throwable cause) {
super(message, cause);
@@ -67,7 +61,6 @@
*
* @param cause
* the cause.
- * @since Android 1.0
*/
public CertificateEncodingException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/cert/CertificateException.java b/security/src/main/java/java/security/cert/CertificateException.java
index 674d617..8b1c4d3 100644
--- a/security/src/main/java/java/security/cert/CertificateException.java
+++ b/security/src/main/java/java/security/cert/CertificateException.java
@@ -21,8 +21,6 @@
/**
* The base class for all {@code Certificate} related exceptions.
- *
- * @since Android 1.0
*/
public class CertificateException extends GeneralSecurityException {
@@ -33,7 +31,6 @@
*
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertificateException(String msg) {
super(msg);
@@ -41,8 +38,6 @@
/**
* Creates a new {@code CertificateException}.
- *
- * @since Android 1.0
*/
public CertificateException() {
}
@@ -55,7 +50,6 @@
* the detail message for the exception.
* @param cause
* the cause.
- * @since Android 1.0
*/
public CertificateException(String message, Throwable cause) {
super(message, cause);
@@ -66,7 +60,6 @@
*
* @param cause
* the cause
- * @since Android 1.0
*/
public CertificateException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/cert/CertificateExpiredException.java b/security/src/main/java/java/security/cert/CertificateExpiredException.java
index fe3fc1f..e15bf98 100644
--- a/security/src/main/java/java/security/cert/CertificateExpiredException.java
+++ b/security/src/main/java/java/security/cert/CertificateExpiredException.java
@@ -19,8 +19,6 @@
/**
* The exception that is thrown when a {@code Certificate} has expired.
- *
- * @since Android 1.0
*/
public class CertificateExpiredException extends CertificateException {
@@ -32,7 +30,6 @@
*
* @param msg
* the detail message for this exception
- * @since Android 1.0
*/
public CertificateExpiredException(String msg) {
super(msg);
@@ -40,8 +37,6 @@
/**
* Creates a new {@code CertificateExpiredException}.
- *
- * @since Android 1.0
*/
public CertificateExpiredException() {
}
diff --git a/security/src/main/java/java/security/cert/CertificateFactory.java b/security/src/main/java/java/security/cert/CertificateFactory.java
index b4213d4..cb2636a 100644
--- a/security/src/main/java/java/security/cert/CertificateFactory.java
+++ b/security/src/main/java/java/security/cert/CertificateFactory.java
@@ -36,9 +36,6 @@
* <p>
* It defines methods for parsing certificate chains (certificate paths) and
* <i>Certificate Revocation Lists</i> (CRLs).
- * </p>
- *
- * @since Android 1.0
*/
public class CertificateFactory {
@@ -59,14 +56,13 @@
/**
* Creates a new {@code CertificateFactory} instance.
- *
+ *
* @param certFacSpi
* the implementation delegate.
* @param provider
* the associated provider.
* @param type
* the certificate type.
- * @since Android 1.0
*/
protected CertificateFactory(CertificateFactorySpi certFacSpi,
Provider provider, String type) {
@@ -87,7 +83,6 @@
* installed provider.
* @throws NullPointerException
* if {@code type} is {@code null}.
- * @since Android 1.0
*/
public static final CertificateFactory getInstance(String type)
throws CertificateException {
@@ -124,7 +119,6 @@
* if the specified provider name is {@code null} or empty.
* @throws NullPointerException
* it {@code type} is {@code null}.
- * @since Android 1.0
*/
public static final CertificateFactory getInstance(String type,
String provider) throws CertificateException,
@@ -156,7 +150,6 @@
* if the specified provider is {@code null}.
* @throws NullPointerException
* is {@code type} is {@code null}.
- * @since Android 1.0
*/
public static final CertificateFactory getInstance(String type,
Provider provider) throws CertificateException {
@@ -182,7 +175,6 @@
* the certificate.
*
* @return the provider of this certificate factory.
- * @since Android 1.0
*/
public final Provider getProvider() {
return provider;
@@ -192,7 +184,6 @@
* Returns the Certificate type.
*
* @return type of certificate being used.
- * @since Android 1.0
*/
public final String getType() {
return type;
@@ -208,7 +199,6 @@
* @return an initialized Certificate.
* @throws CertificateException
* if parsing problems are detected.
- * @since Android 1.0
*/
public final Certificate generateCertificate(InputStream inStream)
throws CertificateException {
@@ -221,7 +211,6 @@
*
* @return an iterator over supported {@link CertPath} encodings (as
* Strings).
- * @since Android 1.0
*/
public final Iterator<String> getCertPathEncodings() {
return spiImpl.engineGetCertPathEncodings();
@@ -236,7 +225,6 @@
* @return a {@code CertPath} initialized from the provided data.
* @throws CertificateException
* if parsing problems are detected.
- * @since Android 1.0
*/
public final CertPath generateCertPath(InputStream inStream)
throws CertificateException {
@@ -261,7 +249,6 @@
* if parsing problems are detected.
* @throws UnsupportedOperationException
* if the provider does not implement this method.
- * @since Android 1.0
*/
public final CertPath generateCertPath(InputStream inStream, String encoding)
throws CertificateException {
@@ -280,7 +267,6 @@
* if parsing problems are detected.
* @throws UnsupportedOperationException
* if the provider does not implement this method.
- * @since Android 1.0
*/
public final CertPath generateCertPath(List<? extends Certificate> certificates)
throws CertificateException {
@@ -297,7 +283,6 @@
* @return an initialized collection of certificates.
* @throws CertificateException
* if parsing problems are detected.
- * @since Android 1.0
*/
public final Collection<? extends Certificate> generateCertificates(InputStream inStream)
throws CertificateException {
@@ -313,7 +298,6 @@
* @return an initialized CRL.
* @exception CRLException
* if parsing problems are detected.
- * @since Android 1.0
*/
public final CRL generateCRL(InputStream inStream) throws CRLException {
return spiImpl.engineGenerateCRL(inStream);
@@ -328,7 +312,6 @@
* @return an initialized collection of CRLs.
* @exception CRLException
* if parsing problems are detected.
- * @since Android 1.0
*/
public final Collection<? extends CRL> generateCRLs(InputStream inStream)
throws CRLException {
diff --git a/security/src/main/java/java/security/cert/CertificateFactorySpi.java b/security/src/main/java/java/security/cert/CertificateFactorySpi.java
index ed6ffed..d9f2044 100644
--- a/security/src/main/java/java/security/cert/CertificateFactorySpi.java
+++ b/security/src/main/java/java/security/cert/CertificateFactorySpi.java
@@ -28,16 +28,12 @@
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for the
* {@code CertificateFactory} class. This SPI must be implemented for each
* certificate type a security provider wishes to support.
- *
- * @since Android 1.0
*/
public abstract class CertificateFactorySpi {
/**
* Constructs a new instance of this class.
- *
- * @since Android 1.0
*/
public CertificateFactorySpi() {
}
@@ -52,7 +48,6 @@
* @return an initialized certificate.
* @exception CertificateException
* if parsing problems are detected.
- * @since Android 1.0
*/
public abstract Certificate engineGenerateCertificate(InputStream inStream)
throws CertificateException;
@@ -66,7 +61,6 @@
* @return a collection of certificates.
* @exception CertificateException
* if parsing problems are detected.
- * @since Android 1.0
*/
public abstract Collection<? extends Certificate>
engineGenerateCertificates(InputStream inStream) throws CertificateException;
@@ -80,7 +74,6 @@
* @return an CRL instance.
* @exception CRLException
* if parsing problems are detected.
- * @since Android 1.0
*/
public abstract CRL engineGenerateCRL(InputStream inStream)
throws CRLException;
@@ -94,7 +87,6 @@
* @return a collection of CRLs.
* @exception CRLException
* if parsing problems are detected.
- * @since Android 1.0
*/
public abstract Collection<? extends CRL>
engineGenerateCRLs(InputStream inStream) throws CRLException;
@@ -108,7 +100,6 @@
* @return a {@code CertPath} initialized from the provided data.
* @throws CertificateException
* if parsing problems are detected.
- * @since Android 1.0
*/
public CertPath engineGenerateCertPath(InputStream inStream)
throws CertificateException {
@@ -130,7 +121,6 @@
* if parsing problems are detected.
* @throws UnsupportedOperationException
* if the provider does not implement this method.
- * @since Android 1.0
*/
public CertPath engineGenerateCertPath(InputStream inStream, String encoding)
throws CertificateException {
@@ -150,7 +140,6 @@
* if parsing problems are detected.
* @throws UnsupportedOperationException
* if the provider does not implement this method.
- * @since Android 1.0
*/
public CertPath engineGenerateCertPath(List<? extends Certificate> certificates)
throws CertificateException {
@@ -164,7 +153,6 @@
*
* @return an iterator over supported {@code CertPath} encodings (as
* Strings).
- * @since Android 1.0
*/
public Iterator<String> engineGetCertPathEncodings() {
throw new UnsupportedOperationException(
diff --git a/security/src/main/java/java/security/cert/CertificateNotYetValidException.java b/security/src/main/java/java/security/cert/CertificateNotYetValidException.java
index 221b22a..dd26bf8 100644
--- a/security/src/main/java/java/security/cert/CertificateNotYetValidException.java
+++ b/security/src/main/java/java/security/cert/CertificateNotYetValidException.java
@@ -20,8 +20,6 @@
/**
* The exception that is thrown when a {@code Certificate} is not yet valid or
* will not yet be valid on a specified date.
- *
- * @since Android 1.0
*/
public class CertificateNotYetValidException extends CertificateException {
@@ -33,7 +31,6 @@
*
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertificateNotYetValidException(String msg) {
super(msg);
@@ -41,8 +38,6 @@
/**
* Creates a new {@code CertificateNotYetValidException}.
- *
- * @since Android 1.0
*/
public CertificateNotYetValidException() {
}
diff --git a/security/src/main/java/java/security/cert/CertificateParsingException.java b/security/src/main/java/java/security/cert/CertificateParsingException.java
index 2c75d20..4efd159 100644
--- a/security/src/main/java/java/security/cert/CertificateParsingException.java
+++ b/security/src/main/java/java/security/cert/CertificateParsingException.java
@@ -19,8 +19,6 @@
/**
* The exception that is thrown when a {@code Certificate} can not be parsed.
- *
- * @since Android 1.0
*/
public class CertificateParsingException extends CertificateException {
@@ -29,10 +27,9 @@
/**
* Creates a new {@code CertificateParsingException} with the specified
* message.
- *
+ *
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertificateParsingException(String msg) {
super(msg);
@@ -40,8 +37,6 @@
/**
* Creates a new {@code CertificateParsingException}.
- *
- * @since Android 1.0
*/
public CertificateParsingException() {
}
@@ -49,12 +44,11 @@
/**
* Creates a new {@code CertificateParsingException} with the specified
* message and cause.
- *
+ *
* @param message
* the detail message for the exception.
* @param cause
* the exception's source.
- * @since Android 1.0
*/
public CertificateParsingException(String message, Throwable cause) {
super(message, cause);
@@ -63,10 +57,9 @@
/**
* Creates a new {@code CertificateParsingException} with the specified
* cause.
- *
+ *
* @param cause
* the exception's source.
- * @since Android 1.0
*/
public CertificateParsingException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/cert/CollectionCertStoreParameters.java b/security/src/main/java/java/security/cert/CollectionCertStoreParameters.java
index 23d8884..3c2fe1c 100644
--- a/security/src/main/java/java/security/cert/CollectionCertStoreParameters.java
+++ b/security/src/main/java/java/security/cert/CollectionCertStoreParameters.java
@@ -24,13 +24,9 @@
* The parameters to initialize a <i>Collection</i> type {@code CertStore} instance.
* <p>
* It is used to specify the {@code Collection} where the {@code CertStore} will
- * retrieve the certificates and CRLs from.
- * </p>
- *
- * @since Android 1.0
+ * retrieve the certificates and CRLs from.
*/
public class CollectionCertStoreParameters implements CertStoreParameters {
- // BEGIN android-changed
// Default empty and immutable collection.
// Used if <code>CollectionCertStoreParameters</code>instance
// created by the no arg constructor
@@ -38,14 +34,11 @@
// A <code>Collection</code> of <code>Certificate</code>s
// and <code>CRL</code>s
private final Collection<?> collection;
- // END android-changed
/**
* Creates a new {@code CollectionCertStoreParameters} without a collection.
* <p>
* The default collection is an empty and unmodifiable {@code Collection}.
- * </p>
- * @since Android 1.0
*/
public CollectionCertStoreParameters() {
this.collection = defaultCollection;
@@ -57,14 +50,12 @@
* <p>
* The specified collection is not copied and therefore may be modified at
* any time.
- * </p>
- *
+ *
* @param collection
* the collection where the {@code Certificate}s and {@code CRL}s
* will be retrieved from.
* @throws NullPointerException
* if {@code collection is null}.
- * @since Android 1.0
*/
public CollectionCertStoreParameters(Collection<?> collection) {
this.collection = collection;
@@ -76,21 +67,23 @@
/**
* Clones this {@code CollectionCertStoreParameters} instance, but not the
* underlying collection.
- *
+ *
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone() {
- return new CollectionCertStoreParameters(collection);
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
}
/**
* Returns the collection where the {@code Certificate}s and {@code CRL}s
* are retrieved from.
- *
+ *
* @return the collection where the {@code Certificate}s and {@code CRL}s
* will be retrieved from.
- * @since Android 1.0
*/
public Collection<?> getCollection() {
return collection;
@@ -98,13 +91,12 @@
/**
* Returns the string representation of this instance.
- *
+ *
* @return the string representation of this instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb =
- new StringBuffer("CollectionCertStoreParameters: [\ncollection: "); //$NON-NLS-1$
+ StringBuilder sb =
+ new StringBuilder("CollectionCertStoreParameters: [\ncollection: "); //$NON-NLS-1$
sb.append(getCollection().toString());
sb.append("\n]"); //$NON-NLS-1$
return sb.toString();
diff --git a/security/src/main/java/java/security/cert/LDAPCertStoreParameters.java b/security/src/main/java/java/security/cert/LDAPCertStoreParameters.java
index 9145848..1d6542f 100644
--- a/security/src/main/java/java/security/cert/LDAPCertStoreParameters.java
+++ b/security/src/main/java/java/security/cert/LDAPCertStoreParameters.java
@@ -19,8 +19,6 @@
/**
* The parameters to initialize a LDAP {@code CertStore} instance.
- *
- * @since Android 1.0
*/
public class LDAPCertStoreParameters implements CertStoreParameters {
// Default LDAP server name
@@ -36,14 +34,13 @@
/**
* Creates a new {@code LDAPCertStoreParameters} instance with the specified
* server name and port.
- *
+ *
* @param serverName
* the LDAP server name.
* @param port
* the port.
* @throws NullPointerException
* is {@code serverName} is {@code null}.
- * @since Android 1.0
*/
public LDAPCertStoreParameters(String serverName, int port) {
this.port = port;
@@ -58,9 +55,6 @@
* parameters.
* <p>
* The default parameters are server name "localhost" and port 389.
- * </p>
- *
- * @since Android 1.0
*/
public LDAPCertStoreParameters() {
this.serverName = DEFAULT_LDAP_SERVER_NAME;
@@ -70,12 +64,11 @@
/**
* Creates a new {@code LDAPCertStoreParameters} instance with the specified
* server name and default port 389.
- *
+ *
* @param serverName
* the LDAP server name.
* @throws NullPointerException
* if {@code serverName} is {@code null}.
- * @since Android 1.0
*/
public LDAPCertStoreParameters(String serverName) {
this.port = DEFAULT_LDAP_PORT;
@@ -87,19 +80,21 @@
/**
* Clones this {@code LDAPCertStoreParameters} instance.
- *
+ *
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone() {
- return new LDAPCertStoreParameters(serverName, port);
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
}
/**
* Returns the LDAP server port.
- *
+ *
* @return the LDAP server port.
- * @since Android 1.0
*/
public int getPort() {
return port;
@@ -107,9 +102,8 @@
/**
* Returns the LDAP server name.
- *
+ *
* @return the LDAP server name.
- * @since Android 1.0
*/
public String getServerName() {
return serverName;
@@ -118,14 +112,13 @@
/**
* Returns the string representation of this {@code LDAPCertStoreParameters}
* instance.
- *
+ *
* @return the string representation of this {@code LDAPCertStoreParameters}
* instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb =
- new StringBuffer("LDAPCertStoreParameters: [\n serverName: "); //$NON-NLS-1$
+ StringBuilder sb =
+ new StringBuilder("LDAPCertStoreParameters: [\n serverName: "); //$NON-NLS-1$
sb.append(getServerName());
sb.append("\n port: "); //$NON-NLS-1$
sb.append(getPort());
diff --git a/security/src/main/java/java/security/cert/PKIXBuilderParameters.java b/security/src/main/java/java/security/cert/PKIXBuilderParameters.java
index a047a80..1a75063 100644
--- a/security/src/main/java/java/security/cert/PKIXBuilderParameters.java
+++ b/security/src/main/java/java/security/cert/PKIXBuilderParameters.java
@@ -32,11 +32,9 @@
* <p>
* The parameters must be created with <i>trusted</i> certificate authorities
* and constraints for the target certificates.
- * </p>
- *
+ *
* @see CertPathBuilder
* @see CertPathParameters
- * @since Android 1.0
*/
public class PKIXBuilderParameters extends PKIXParameters {
// Maximum certificate path length (5 by default)
@@ -55,7 +53,6 @@
* @throws ClassCastException
* if one of the items in {@code trustAnchors} is not an
* instance of {@code java.security.cert.TrustAnchor}.
- * @since Android 1.0
*/
public PKIXBuilderParameters(Set<TrustAnchor> trustAnchors,
CertSelector targetConstraints)
@@ -77,7 +74,6 @@
* @throws InvalidAlgorithmParameterException
* if {@code keyStore} does not contained any trusted
* certificate entry.
- * @since Android 1.0
*/
public PKIXBuilderParameters(KeyStore keyStore,
CertSelector targetConstraints)
@@ -92,11 +88,9 @@
* <p>
* This is the maximum number of non-self-signed certificates in a
* certification path.
- * </p>
- *
+ *
* @return the maximum length of a certification path, or {@code -1} if it
* is unlimited.
- * @since Android 1.0
*/
public int getMaxPathLength() {
return maxPathLength;
@@ -107,13 +101,11 @@
* <p>
* This is the maximum number of non-self-signed certificates in a
* certification path.
- * </p>
*
* @param maxPathLength
* the maximum length of a certification path.
* @throws InvalidParameterException
* if {@code maxPathLength} is less than {@code -1}.
- * @since Android 1.0
*/
public void setMaxPathLength(int maxPathLength) {
if (maxPathLength < -1) {
@@ -129,10 +121,9 @@
*
* @return a string representation of this {@code PKIXBuilderParameters}
* instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb = new StringBuffer("[\n"); //$NON-NLS-1$
+ StringBuilder sb = new StringBuilder("[\n"); //$NON-NLS-1$
sb.append(super.toString());
sb.append(" Max Path Length: "); //$NON-NLS-1$
sb.append(maxPathLength);
diff --git a/security/src/main/java/java/security/cert/PKIXCertPathBuilderResult.java b/security/src/main/java/java/security/cert/PKIXCertPathBuilderResult.java
index 6064194..5a9fb2d 100644
--- a/security/src/main/java/java/security/cert/PKIXCertPathBuilderResult.java
+++ b/security/src/main/java/java/security/cert/PKIXCertPathBuilderResult.java
@@ -25,8 +25,6 @@
/**
* The result of the PKIX certification path builder, returned by
* {@link CertPathBuilder#build(CertPathParameters)}.
- *
- * @since Android 1.0
*/
public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult
implements CertPathBuilderResult {
@@ -49,7 +47,6 @@
* @throws NullPointerException
* if the {@code cerPath}, {@code trustAnchor} or {@code
* subjectPolicyKey} is {@code null}.
- * @since Android 1.0
*/
public PKIXCertPathBuilderResult(CertPath certPath, TrustAnchor trustAnchor,
PolicyNode policyTree, PublicKey subjectPublicKey) {
@@ -64,7 +61,6 @@
* Returns the validated certification path.
*
* @return the validated certification path.
- * @since Android 1.0
*/
public CertPath getCertPath() {
return certPath;
@@ -76,10 +72,9 @@
*
* @return a string representation of this {@code PKIXCertPathBuilderResult}
* instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb = new StringBuffer(super.toString());
+ StringBuilder sb = new StringBuilder(super.toString());
sb.append("\n Certification Path: "); //$NON-NLS-1$
sb.append(certPath.toString());
sb.append("\n]"); //$NON-NLS-1$
diff --git a/security/src/main/java/java/security/cert/PKIXCertPathChecker.java b/security/src/main/java/java/security/cert/PKIXCertPathChecker.java
index 5614878..5eaac74 100644
--- a/security/src/main/java/java/security/cert/PKIXCertPathChecker.java
+++ b/security/src/main/java/java/security/cert/PKIXCertPathChecker.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Vladimir N. Molotkov
-* @version $Revision$
-*/
-
package java.security.cert;
import java.util.Collection;
@@ -38,22 +33,16 @@
* {@link #check(Certificate, Collection) check} method will be called for each
* certificate processed by a {@code CertPathBuilder} of {@code
* CertPathValidator}.
- * </p>
* <p>
* A {@code PKIXCertPathChecker} implementation <u>must</u> support reverse
* checking (from trusted CA to target) and <u>may</u> support forward checking
* (from target to trusted CA). The return value of {@code
* isForwardCheckingSupported} indicates whether forward checking is supported.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class PKIXCertPathChecker implements Cloneable {
/**
* Creates a new {@code PKIXCertPathChecker} instance.
- *
- * @since Android 1.0
*/
protected PKIXCertPathChecker() {}
@@ -61,13 +50,12 @@
* Clones this {@code PKIXCertPathChecker} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- throw new Error(e);
+ throw new AssertionError(e); // android-changed
}
}
@@ -84,7 +72,6 @@
* if initialization of this {@code PKIXCertPathChecker}
* instance fails, or if it cannot process certificates in the
* specified order.
- * @since Android 1.0
*/
public abstract void init(boolean forward)
throws CertPathValidatorException;
@@ -95,7 +82,6 @@
*
* @return {@code true} if this {@code PKIXCertPathChecker} instance
* supports forward checking, otherwise {@code false}.
- * @since Android 1.0
*/
public abstract boolean isForwardCheckingSupported();
@@ -106,7 +92,6 @@
* @return the list of extensions of X.509 certificates that this {@code
* PKIXCertPathChecker} is able to process, or {@code null} if there
* are none.
- * @since Android 1.0
*/
public abstract Set<String> getSupportedExtensions();
@@ -120,7 +105,6 @@
* the list of critical X.509 extension OID strings.
* @throws CertPathValidatorException
* if check(s) fail on the specified certificate.
- * @since Android 1.0
*/
public abstract void check(Certificate cert, Collection<String> unresolvedCritExts)
throws CertPathValidatorException;
diff --git a/security/src/main/java/java/security/cert/PKIXCertPathValidatorResult.java b/security/src/main/java/java/security/cert/PKIXCertPathValidatorResult.java
index 21f90c9..d82c699 100644
--- a/security/src/main/java/java/security/cert/PKIXCertPathValidatorResult.java
+++ b/security/src/main/java/java/security/cert/PKIXCertPathValidatorResult.java
@@ -26,7 +26,6 @@
*
* @see CertPathValidator
* @see CertPathValidator#validate(CertPath, CertPathParameters)
- * @since Android 1.0
*/
public class PKIXCertPathValidatorResult implements CertPathValidatorResult {
// A trust anchor used during validation of certification path
@@ -48,7 +47,6 @@
* the valid policy tree from the validation.
* @param subjectPublicKey
* the subject public key from the validation.
- * @since Android 1.0
*/
public PKIXCertPathValidatorResult(TrustAnchor trustAnchor,
PolicyNode policyTree, PublicKey subjectPublicKey) {
@@ -68,7 +66,6 @@
* Returns the valid policy tree from the validation.
*
* @return the valid policy tree from the validation.
- * @since Android 1.0
*/
public PolicyNode getPolicyTree() {
return policyTree;
@@ -78,7 +75,6 @@
* Returns the subject public key from the validation.
*
* @return the subject public key from the validation.
- * @since Android 1.0
*/
public PublicKey getPublicKey() {
return subjectPublicKey;
@@ -89,7 +85,6 @@
* served as trust anchor for this certification path.
*
* @return the trust anchor.
- * @since Android 1.0
*/
public TrustAnchor getTrustAnchor() {
return trustAnchor;
@@ -99,14 +94,12 @@
* Clones this {@code PKIXCertPathValidatorResult} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- // Actually, the exception will not be thrown out.
- throw new Error(e);
+ throw new AssertionError(e); // android-changed
}
}
@@ -116,10 +109,9 @@
*
* @return a string representation for this {@code
* PKIXCertPathValidatorResult} instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb = new StringBuffer(super.toString());
+ StringBuilder sb = new StringBuilder(super.toString());
sb.append(": [\n Trust Anchor: "); //$NON-NLS-1$
sb.append(trustAnchor.toString());
sb.append("\n Policy Tree: "); //$NON-NLS-1$
diff --git a/security/src/main/java/java/security/cert/PKIXParameters.java b/security/src/main/java/java/security/cert/PKIXParameters.java
index 16b0686..79d3d5e 100644
--- a/security/src/main/java/java/security/cert/PKIXParameters.java
+++ b/security/src/main/java/java/security/cert/PKIXParameters.java
@@ -36,11 +36,9 @@
* <p>
* The parameters must be created with <i>trusted</i> certificate authorities
* (trust anchors).
- * </p>
- *
+ *
* @see CertPathValidator
* @see CertPathParameters
- * @since Android 1.0
*/
public class PKIXParameters implements CertPathParameters {
// Set of trust anchors - most trusted CAs
@@ -79,7 +77,6 @@
* the trusted CAs.
* @throws InvalidAlgorithmParameterException
* if {@code trustAnchors} is empty.
- * @since Android 1.0
*/
public PKIXParameters(Set<TrustAnchor> trustAnchors)
throws InvalidAlgorithmParameterException {
@@ -101,7 +98,6 @@
* @throws InvalidAlgorithmParameterException
* if {@code keyStore} does not contained any trusted
* certificate entry.
- * @since Android 1.0
*/
public PKIXParameters(KeyStore keyStore)
throws KeyStoreException,
@@ -137,7 +133,6 @@
* Returns a unmodifiable set of the <i>trusted</i> certificate authorities.
*
* @return a unmodifiable set of the <i>trusted</i> certificate authorities.
- * @since Android 1.0
*/
public Set<TrustAnchor> getTrustAnchors() {
return Collections.unmodifiableSet(trustAnchors);
@@ -150,7 +145,6 @@
* the set of <i>trusted</i> certificate authorities.
* @throws InvalidAlgorithmParameterException
* if {@code trustAnchors} is empty.
- * @since Android 1.0
*/
public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
throws InvalidAlgorithmParameterException {
@@ -169,7 +163,6 @@
*
* @return {@code true} if the <i>any policy OID</i> will be inhibited,
* otherwise {@code false}.
- * @since Android 1.0
*/
public boolean isAnyPolicyInhibited() {
return anyPolicyInhibited;
@@ -182,7 +175,6 @@
* @param anyPolicyInhibited
* {@code true} if the <i>any policy OID</i> should be inhibited,
* otherwise {@code false}.
- * @since Android 1.0
*/
public void setAnyPolicyInhibited(boolean anyPolicyInhibited) {
this.anyPolicyInhibited = anyPolicyInhibited;
@@ -192,10 +184,8 @@
* Returns the list of checkers for the certification path.
* <p>
* The list is unmodifiable and the entries in the list are cloned.
- * </p>
- *
+ *
* @return the list of checkers for the certification path.
- * @since Android 1.0
*/
public List<PKIXCertPathChecker> getCertPathCheckers() {
if (certPathCheckers == null) {
@@ -222,12 +212,10 @@
* Sets the list of checkers for the certification path.
* <p>
* The list is copied and the entries are cloned.
- * </p>
*
* @param certPathCheckers
* the list of checkers for the certification path, or {@code
* null} to clear the checkers.
- * @since Android 1.0
*/
public void setCertPathCheckers(List<PKIXCertPathChecker> certPathCheckers) {
if (certPathCheckers == null || certPathCheckers.isEmpty()) {
@@ -254,7 +242,6 @@
* @param checker
* the {@code PKIXCertPathChecker} to add, if {@code null}, it
* will be ignored.
- * @since Android 1.0
*/
public void addCertPathChecker(PKIXCertPathChecker checker) {
if (checker == null) {
@@ -274,7 +261,6 @@
* and CRLs.
*
* @return an immutable list of certificate stores.
- * @since Android 1.0
*/
public List<CertStore> getCertStores() {
if (certStores == null) {
@@ -298,7 +284,6 @@
* CRLs.
*
* @param certStores the list of certificate stores.
- * @since Android 1.0
*/
public void setCertStores(List<CertStore> certStores) {
if (certStores == null || certStores.isEmpty()) {
@@ -325,7 +310,6 @@
*
* @param store
* the store to add, if {@code null}, it will be ignored.
- * @since Android 1.0
*/
public void addCertStore(CertStore store) {
if (store == null) {
@@ -346,7 +330,6 @@
*
* @return the time for the validation, or {@code null} for the current
* time.
- * @since Android 1.0
*/
public Date getDate() {
return date == null ? null : (Date)date.clone();
@@ -359,7 +342,6 @@
* @param date
* the time for the validation, or {@code null} for the current
* time.
- * @since Android 1.0
*/
public void setDate(Date date) {
this.date = (date == null ? null : new Date(date.getTime()));
@@ -371,7 +353,6 @@
*
* @return {@code true} if an explicit policy is required, otherwise {@code
* false}.
- * @since Android 1.0
*/
public boolean isExplicitPolicyRequired() {
return explicitPolicyRequired;
@@ -384,7 +365,6 @@
* @param explicitPolicyRequired
* {@code true} if an explicit policy is required, otherwise
* {@code false}.
- * @since Android 1.0
*/
public void setExplicitPolicyRequired(boolean explicitPolicyRequired) {
this.explicitPolicyRequired = explicitPolicyRequired;
@@ -396,7 +376,6 @@
*
* @return the unmodifiable list of policies, or an empty set if any policy
* is acceptable.
- * @since Android 1.0
*/
public Set<String> getInitialPolicies() {
if (initialPolicies == null) {
@@ -421,7 +400,6 @@
* @param initialPolicies
* the list of policies, or an empty set or {@code null} if any
* policy is acceptable.
- * @since Android 1.0
*/
public void setInitialPolicies(Set<String> initialPolicies) {
if (initialPolicies == null || initialPolicies.isEmpty()) {
@@ -448,7 +426,6 @@
*
* @return {@code true} if policy mapping is inhibited, otherwise {@code
* false}.
- * @since Android 1.0
*/
public boolean isPolicyMappingInhibited() {
return policyMappingInhibited;
@@ -460,7 +437,6 @@
* @param policyMappingInhibited
* {@code true} if policy mapping is to be inhibited, otherwise
* {@code false}.
- * @since Android 1.0
*/
public void setPolicyMappingInhibited(boolean policyMappingInhibited) {
this.policyMappingInhibited = policyMappingInhibited;
@@ -472,7 +448,6 @@
*
* @return {@code true} if the certificates should be rejected, otherwise
* {@code false}.
- * @since Android 1.0
*/
public boolean getPolicyQualifiersRejected() {
return policyQualifiersRejected;
@@ -485,7 +460,6 @@
* @param policyQualifiersRejected
* {@code true} if the certificates should be rejected, otherwise
* {@code false}.
- * @since Android 1.0
*/
public void setPolicyQualifiersRejected(boolean policyQualifiersRejected) {
this.policyQualifiersRejected = policyQualifiersRejected;
@@ -497,7 +471,6 @@
*
* @return {@code true} if the default revocation checking mechanism is
* used, otherwise {@code false}.
- * @since Android 1.0
*/
public boolean isRevocationEnabled() {
return revocationEnabled;
@@ -510,7 +483,6 @@
* @param revocationEnabled
* {@code true} id the default revocation checking mechanism
* should be used, otherwise {@code false}.
- * @since Android 1.0
*/
public void setRevocationEnabled(boolean revocationEnabled) {
this.revocationEnabled = revocationEnabled;
@@ -521,7 +493,6 @@
*
* @return the name of the signature provider, or {@code null} if none is
* set.
- * @since Android 1.0
*/
public String getSigProvider() {
return sigProvider;
@@ -537,7 +508,6 @@
* @param sigProvider
* the name of the preferred signature provider, or {@code null}
* if none is preferred.
- * @since Android 1.0
*/
public void setSigProvider(String sigProvider) {
this.sigProvider = sigProvider;
@@ -548,7 +518,6 @@
*
* @return the constraints for the target certificate, or {@code null} if
* none are set.
- * @since Android 1.0
*/
public CertSelector getTargetCertConstraints() {
return (targetCertConstraints == null ? null
@@ -561,7 +530,6 @@
* @param targetCertConstraints
* the constraints for the target certificate, or {@code null} if
* none should be used.
- * @since Android 1.0
*/
public void setTargetCertConstraints(CertSelector targetCertConstraints) {
this.targetCertConstraints = (targetCertConstraints == null ? null
@@ -572,7 +540,6 @@
* Clones this {@code PKIXParameters} instance.
*
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone() {
try {
@@ -587,7 +554,7 @@
}
return ret;
} catch (CloneNotSupportedException e) {
- throw new Error(e);
+ throw new AssertionError(e); // android-changed
}
}
@@ -595,11 +562,10 @@
* Returns a string representation of this {@code PKIXParameters} instance.
*
* @return a string representation of this {@code PKIXParameters} instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb =
- new StringBuffer("[\n Trust Anchors: "); //$NON-NLS-1$
+ StringBuilder sb =
+ new StringBuilder("[\n Trust Anchors: "); //$NON-NLS-1$
sb.append(trustAnchors);
sb.append("\n Revocation Enabled: "); //$NON-NLS-1$
sb.append(revocationEnabled);
diff --git a/security/src/main/java/java/security/cert/PolicyNode.java b/security/src/main/java/java/security/cert/PolicyNode.java
index c112a8a..c485b69 100644
--- a/security/src/main/java/java/security/cert/PolicyNode.java
+++ b/security/src/main/java/java/security/cert/PolicyNode.java
@@ -26,9 +26,6 @@
* <p>
* Instances of this class are one of the outputs of the PKIX certification path
* validation algorithm.
- * </p>
- *
- * @since Android 1.0
*/
public interface PolicyNode {
@@ -36,7 +33,6 @@
* Returns the list of children of this node as an {@code Iterator}.
*
* @return the list of children of this node as an {@code Iterator}.
- * @since Android 1.0
*/
public Iterator<? extends PolicyNode> getChildren();
@@ -44,10 +40,8 @@
* Returns the depth of this node in the policy tree.
* <p>
* the depth is zero based.
- * </p>
*
* @return the depth of this node in the policy tree.
- * @since Android 1.0
*/
public int getDepth();
@@ -55,7 +49,6 @@
* Returns the expected policies for the next certificate to be valid.
*
* @return the expected policies.
- * @since Android 1.0
*/
public Set<String> getExpectedPolicies();
@@ -63,7 +56,6 @@
* Returns the parent policy node.
*
* @return the parent policy node.
- * @since Android 1.0
*/
public PolicyNode getParent();
@@ -71,7 +63,6 @@
* Returns the policy qualifiers associated with the policy of this node.
*
* @return the policy qualifiers associated with the policy of this node.
- * @since Android 1.0
*/
public Set<? extends PolicyQualifierInfo> getPolicyQualifiers();
@@ -79,7 +70,6 @@
* Returns the valid policy of this node.
*
* @return the valid policy of this node.
- * @since Android 1.0
*/
public String getValidPolicy();
@@ -89,7 +79,6 @@
*
* @return {@code true} if the extension is marked as critical, otherwise
* {@code false}.
- * @since Android 1.0
*/
public boolean isCritical();
}
diff --git a/security/src/main/java/java/security/cert/PolicyQualifierInfo.java b/security/src/main/java/java/security/cert/PolicyQualifierInfo.java
index 5a63d51..903a6e9 100644
--- a/security/src/main/java/java/security/cert/PolicyQualifierInfo.java
+++ b/security/src/main/java/java/security/cert/PolicyQualifierInfo.java
@@ -27,8 +27,6 @@
/**
* This class implements a policy qualifier as defined by the ASN.1
* {@code PolicyQualifierInfo} structure.
- *
- * @since Android 1.0
*/
public class PolicyQualifierInfo {
// This PolicyQualifierInfo DER encoding
@@ -48,7 +46,6 @@
* the DER encoded policy qualifier.
* @throws IOException
* the policy qualifier cannot be decoded.
- * @since Android 1.0
*/
public PolicyQualifierInfo(byte[] encoded) throws IOException {
if (encoded == null) {
@@ -71,7 +68,6 @@
* Returns a ASN.1 DER encoded copy of policy qualifier info.
*
* @return a ASN.1 DER encoded copy of policy qualifier info.
- * @since Android 1.0
*/
public final byte[] getEncoded() {
byte[] ret = new byte[encoded.length];
@@ -83,7 +79,6 @@
* Returns the identifier (an OID) of this policy qualifier info.
*
* @return the identifier of this policy qualifier info.
- * @since Android 1.0
*/
public final String getPolicyQualifierId() {
return policyQualifierId;
@@ -95,7 +90,6 @@
*
* @return a ASN.1 DER encoded copy of the qualifier of this policy
* qualifier info.
- * @since Android 1.0
*/
public final byte[] getPolicyQualifier() {
if (policyQualifier == null) {
@@ -112,11 +106,10 @@
*
* @return a string representation of this {@code PolicyQualifierInfo}
* instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb =
- new StringBuffer("PolicyQualifierInfo: [\npolicyQualifierId: "); //$NON-NLS-1$
+ StringBuilder sb =
+ new StringBuilder("PolicyQualifierInfo: [\npolicyQualifierId: "); //$NON-NLS-1$
sb.append(policyQualifierId);
sb.append("\npolicyQualifier: \n"); //$NON-NLS-1$
sb.append(Array.toString(policyQualifier, " ")); //$NON-NLS-1$
diff --git a/security/src/main/java/java/security/cert/TrustAnchor.java b/security/src/main/java/java/security/cert/TrustAnchor.java
index 9dc2025..eae38d6 100644
--- a/security/src/main/java/java/security/cert/TrustAnchor.java
+++ b/security/src/main/java/java/security/cert/TrustAnchor.java
@@ -36,9 +36,6 @@
* of the CA, the CA's name and the constraints for the validation of
* certification paths. The constructor also allows to specify a binary
* representation of a so called "Name Constraints" extension as a byte array.
- * </p>
- *
- * @since Android 1.0
*/
public class TrustAnchor {
// Most trusted CA as a X500Principal
@@ -58,8 +55,7 @@
* <p>
* The name constraints will be used as additional constraints during the
* validation of certification paths.
- * </p>
- *
+ *
* @param trustedCert
* the trusted certificate
* @param nameConstraints
@@ -67,7 +63,6 @@
* null} if none.
* @throws IllegalArgumentException
* if the decoding of the name constraints fail.
- * @since Android 1.0
*/
public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) {
if (trustedCert == null) {
@@ -94,8 +89,7 @@
* <p>
* The name constraints will be used as additional constraints during the
* validation of certification paths.
- * </p>
- *
+ *
* @param caName
* the X.500 name of the certificate authority in RFC 2253
* {@code String} format.
@@ -107,7 +101,6 @@
* @throws IllegalArgumentException
* if the {@code caName} is empty or if decoding of the name
* constraints fail.
- * @since Android 1.0
*/
public TrustAnchor(String caName, PublicKey caPublicKey,
byte[] nameConstraints) {
@@ -146,7 +139,6 @@
* <p>
* The name constraints will be used as additional constraints during the
* validation of certification paths.
- * </p>
*
* @param caPrincipal
* the name of the certificate authority as X500 principal.
@@ -157,7 +149,6 @@
* null} if none.
* @throws IllegalArgumentException
* if decoding of the name constraints fail.
- * @since Android 1.0
*/
public TrustAnchor(X500Principal caPrincipal,
PublicKey caPublicKey, byte[] nameConstraints) {
@@ -187,7 +178,6 @@
* Returns a copy of the name constraints in ASN.1 DER encoded form.
*
* @return a copy of the name constraints in ASN.1 DER encoded form.
- * @since Android 1.0
*/
public final byte[] getNameConstraints() {
if (nameConstraints == null) {
@@ -204,7 +194,6 @@
*
* @return the certificate of this CA or {@code null}, if the trust anchor
* of this instance was not created with a certificate.
- * @since Android 1.0
*/
public final X509Certificate getTrustedCert() {
return trustedCert;
@@ -216,7 +205,6 @@
* @return the name of the certificate authority or {@code null} if the
* trust anchor of this instance was not created with a {@code
* X500Principal}.
- * @since Android 1.0
*/
public final X500Principal getCA() {
return caPrincipal;
@@ -229,7 +217,6 @@
* @return the name of the certificate authority as {@code String} in RFC
* 2253 format or {@code null} if the trust anchor of this instance
* was not created with a CA name.
- * @since Android 1.0
*/
public final String getCAName() {
return caName;
@@ -241,7 +228,6 @@
* @return the public key of the certificate authority or {@code null} if
* the trust anchor if this instance was not created with a public
* key.
- * @since Android 1.0
*/
public final PublicKey getCAPublicKey() {
return caPublicKey;
@@ -251,10 +237,9 @@
* Returns a string representation of this {@code TrustAnchor} instance.
*
* @return a string representation of this {@code TrustAnchor} instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer sb = new StringBuffer("TrustAnchor: [\n"); //$NON-NLS-1$
+ StringBuilder sb = new StringBuilder("TrustAnchor: [\n"); //$NON-NLS-1$
if (trustedCert != null) {
sb.append("Trusted CA certificate: "); //$NON-NLS-1$
sb.append(trustedCert);
diff --git a/security/src/main/java/java/security/cert/X509CRL.java b/security/src/main/java/java/security/cert/X509CRL.java
index eabdb68..cb99843 100644
--- a/security/src/main/java/java/security/cert/X509CRL.java
+++ b/security/src/main/java/java/security/cert/X509CRL.java
@@ -44,16 +44,11 @@
* href
* ="http://www.ietf.org/rfc/rfc2459.txt">http://www.ietf.org/rfc/rfc2459.txt
* </a>.
- * </p>
- *
- * @since Android 1.0
*/
public abstract class X509CRL extends CRL implements X509Extension {
/**
* Creates a new {@code X509CRL} instance.
- *
- * @since Android 1.0
*/
protected X509CRL() {
super("X.509"); //$NON-NLS-1$
@@ -66,7 +61,6 @@
* the object to compare.
* @return {@code true} if the specified object is equal to this, otherwise
* {@code false}.
- * @since Android 1.0
*/
public boolean equals(Object other) {
if (other == this) {
@@ -87,7 +81,6 @@
* Returns the hashcode of this CRL instance.
*
* @return the hashcode.
- * @since Android 1.0
*/
public int hashCode() {
try {
@@ -108,7 +101,6 @@
* @return this CRL in ASN.1 DER encoded form.
* @throws CRLException
* if encoding fails.
- * @since Android 1.0
*/
public abstract byte[] getEncoded() throws CRLException;
@@ -129,7 +121,6 @@
* if no provider can be found.
* @throws SignatureException
* if errors occur on signatures.
- * @since Android 1.0
*/
public abstract void verify(PublicKey key)
throws CRLException, NoSuchAlgorithmException,
@@ -155,7 +146,6 @@
* if the specified provider cannot be found.
* @throws SignatureException
* if errors occur on signatures.
- * @since Android 1.0
*/
public abstract void verify(PublicKey key, String sigProvider)
throws CRLException, NoSuchAlgorithmException,
@@ -166,7 +156,6 @@
* Returns the version number of this CRL.
*
* @return the version number of this CRL.
- * @since Android 1.0
*/
public abstract int getVersion();
@@ -175,7 +164,6 @@
* the issuer as an implementation specific Principal object.
*
* @return the issuer distinguished name.
- * @since Android 1.0
*/
public abstract Principal getIssuerDN();
@@ -183,7 +171,6 @@
* Returns the issuer distinguished name of this CRL.
*
* @return the issuer distinguished name of this CRL.
- * @since Android 1.0
*/
public X500Principal getIssuerX500Principal() {
try {
@@ -206,7 +193,6 @@
* Returns the {@code thisUpdate} value of this CRL.
*
* @return the {@code thisUpdate} value of this CRL.
- * @since Android 1.0
*/
public abstract Date getThisUpdate();
@@ -215,7 +201,6 @@
*
* @return the {@code nextUpdate} value of this CRL, or {@code null} if none
* is present.
- * @since Android 1.0
*/
public abstract Date getNextUpdate();
@@ -226,7 +211,6 @@
* the certificate serial number to search for a CRL entry.
* @return the entry for the specified certificate serial number, or {@code
* null} if not found.
- * @since Android 1.0
*/
public abstract X509CRLEntry getRevokedCertificate(BigInteger serialNumber);
@@ -237,7 +221,6 @@
* the certificate to search a CRL entry for.
* @return the entry for the specified certificate, or {@code null} if not
* found.
- * @since Android 1.0
*/
public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
if (certificate == null) {
@@ -251,7 +234,6 @@
*
* @return the set of revoked certificates, or {@code null} if no revoked
* certificates are in this CRL.
- * @since Android 1.0
*/
public abstract Set<? extends X509CRLEntry> getRevokedCertificates();
@@ -262,7 +244,6 @@
* @return the CRL information in DER encoded form.
* @throws CRLException
* if encoding fails.
- * @since Android 1.0
*/
public abstract byte[] getTBSCertList() throws CRLException;
@@ -270,7 +251,6 @@
* Returns the signature bytes of this CRL.
*
* @return the signature bytes of this CRL.
- * @since Android 1.0
*/
public abstract byte[] getSignature();
@@ -278,7 +258,6 @@
* Returns the name of the signature algorithm.
*
* @return the name of the signature algorithm.
- * @since Android 1.0
*/
public abstract String getSigAlgName();
@@ -286,7 +265,6 @@
* Returns the OID of the signature algorithm.
*
* @return the OID of the signature algorithm.
- * @since Android 1.0
*/
public abstract String getSigAlgOID();
@@ -295,7 +273,6 @@
*
* @return the parameters of the signature algorithm in DER encoded form, or
* {@code null} if not present.
- * @since Android 1.0
*/
public abstract byte[] getSigAlgParams();
}
diff --git a/security/src/main/java/java/security/cert/X509CRLEntry.java b/security/src/main/java/java/security/cert/X509CRLEntry.java
index 35fb78b..ccdaf2f 100644
--- a/security/src/main/java/java/security/cert/X509CRLEntry.java
+++ b/security/src/main/java/java/security/cert/X509CRLEntry.java
@@ -29,14 +29,11 @@
* Abstract base class for entries in a certificate revocation list (CRL).
*
* @see X509CRL
- * @since Android 1.0
*/
public abstract class X509CRLEntry implements X509Extension {
/**
* Creates a new {@code X509CRLEntry} instance.
- *
- * @since Android 1.0
*/
public X509CRLEntry() {}
@@ -47,7 +44,6 @@
* the object to compare.
* @return {@code true} if the specified object equals to this instance,
* otherwise {@code false}.
- * @since Android 1.0
*/
public boolean equals(Object other) {
if (other == this) {
@@ -68,7 +64,6 @@
* Returns the hashcode of this instance.
*
* @return the hashcode of this instance.
- * @since Android 1.0
*/
public int hashCode() {
int res = 0;
@@ -88,7 +83,6 @@
* @return the encoded form of this entry.
* @throws CRLException
* if encoding fails.
- * @since Android 1.0
*/
public abstract byte[] getEncoded() throws CRLException;
@@ -96,7 +90,6 @@
* Returns the serial number of the revoked certificate.
*
* @return the serial number of the revoked certificate.
- * @since Android 1.0
*/
public abstract BigInteger getSerialNumber();
@@ -105,7 +98,6 @@
*
* @return the issuer of the revoked certificate, or {@code null} if the
* issuer is equal to the CRL issuer.
- * @since Android 1.0
*/
public X500Principal getCertificateIssuer() {
return null;
@@ -115,7 +107,6 @@
* Returns the date when the certificate is revoked.
*
* @return the date when the certificate is revoked.
- * @since Android 1.0
*/
public abstract Date getRevocationDate();
@@ -124,7 +115,6 @@
*
* @return {@code true} is this CRL entry has extensions, otherwise {@code
* false}.
- * @since Android 1.0
*/
public abstract boolean hasExtensions();
@@ -132,7 +122,6 @@
* Returns a string representation of this instance.
*
* @return a string representation of this instance.
- * @since Android 1.0
*/
public abstract String toString();
}
diff --git a/security/src/main/java/java/security/cert/X509CRLSelector.java b/security/src/main/java/java/security/cert/X509CRLSelector.java
index c1b5f45..0edddf4 100644
--- a/security/src/main/java/java/security/cert/X509CRLSelector.java
+++ b/security/src/main/java/java/security/cert/X509CRLSelector.java
@@ -36,10 +36,7 @@
* X509CRL}s that match the specified criteria.
* <p>
* When constructed, all criteria are set to default values that will match any
- * {@code X509CRL}.
- * </p>
- *
- * @since Android 1.0
+ * {@code X509CRL}.
*/
public class X509CRLSelector implements CRLSelector {
@@ -60,8 +57,6 @@
/**
* Creates a new {@code X509CertSelector}.
- *
- * @since Android 1.0
*/
public X509CRLSelector() { }
@@ -70,12 +65,10 @@
* <p>
* The CRL issuer must match at least one of the specified distinguished
* names.
- * </p>
- *
+ *
* @param issuers
* the list of issuer distinguished names to match, or {@code
* null} if any issuer distinguished name will do.
- * @since Android 1.0
*/
public void setIssuers(Collection<X500Principal> issuers) {
if (issuers == null) {
@@ -97,20 +90,17 @@
* <p>
* The CRL issuer must match at least one of the specified distinguished
* names.
- * </p>
* <p>
* The specified parameter {@code names} is a collection with an entry for
* each name to be included in the criterion. The name is specified as a
* {@code String} or a byte array specifying the name (in RFC 2253 or ASN.1
* DER encoded form)
- * </p>
- *
+ *
* @param names
* the list of issuer distinguished names to match, or {@code
* null} if any issuer distinguished name will do.
* @throws IOException
* if parsing fails.
- * @since Android 1.0
*/
public void setIssuerNames(Collection<?> names) throws IOException {
if (names == null) {
@@ -143,11 +133,9 @@
* <p>
* The CRL issuer must match at least one of the specified distinguished
* names.
- * </p>
- *
+ *
* @param issuer
* the issuer to add to the criterion
- * @since Android 1.0
*/
public void addIssuer(X500Principal issuer) {
if (issuer == null) {
@@ -178,13 +166,11 @@
* <p>
* Adds an issuer to the criterion for the issuer distinguished names. The
* CRK issuer must match at least one of the specified distinguished names.
- * </p>
- *
+ *
* @param iss_name
* the RFC 2253 encoded name.
* @throws IOException
* if parsing fails.
- * @since Android 1.0
*/
public void addIssuerName(String iss_name) throws IOException {
if (issuerNames == null) {
@@ -206,13 +192,11 @@
* <p>
* The CRL issuer must match at least one of the specified distinguished
* names.
- * </p>
- *
+ *
* @param iss_name
* the issuer to add to the criterion in ASN.1 DER encoded form.
* @throws IOException
* if parsing fails.
- * @since Android 1.0
*/
public void addIssuerName(byte[] iss_name) throws IOException {
if (iss_name == null) {
@@ -232,12 +216,10 @@
* <p>
* The CRL must have a number extension with a value greater than or equal
* to the specified parameter.
- * </p>
- *
+ *
* @param minCRL
* the minimum CRL number or null to not check the minimum CRL
* number
- * @since Android 1.0
*/
public void setMinCRLNumber(BigInteger minCRL) {
this.minCRL = minCRL;
@@ -248,12 +230,10 @@
* <p>
* The CRL must have a number extension with a value less than or equal to
* the specified parameter.
- * </p>
- *
+ *
* @param maxCRL
* the maximum CRL number or null to not check the maximum CRL
* number.
- * @since Android 1.0
*/
public void setMaxCRLNumber(BigInteger maxCRL) {
this.maxCRL = maxCRL;
@@ -264,12 +244,10 @@
* <p>
* The CRL's {@code thisUpdate} value must be equal or before the specified
* date and the {@code nextUpdate} value must be after the specified date.
- * </p>
- *
+ *
* @param dateAndTime
* the date to search for valid CRL's or {@code null} to not
* check the date.
- * @since Android 1.0
*/
public void setDateAndTime(Date dateAndTime) {
if (dateAndTime == null) {
@@ -282,10 +260,9 @@
/**
* Sets a certificate hint to find CRLs. It's not a criterion but may help
* finding relevant CRLs.
- *
+ *
* @param cert
* the certificate hint or {@code null}.
- * @since Android 1.0
*/
public void setCertificateChecking(X509Certificate cert) {
this.certificateChecking = cert;
@@ -295,11 +272,9 @@
* Returns the criterion for the issuer distinguished names.
* <p>
* The CRL issuer must match at least one of the distinguished names.
- * </p>
- *
+ *
* @return the unmodifiable list of issuer distinguished names to match, or
* {@code null} if any issuer distinguished name will do.
- * @since Android 1.0
*/
public Collection<X500Principal> getIssuers() {
if (issuerNames == null) {
@@ -320,11 +295,9 @@
* Returns the criterion for the issuer distinguished names.
* <p>
* The CRL issuer must match at least one of the distinguished names.
- * </p>
- *
+ *
* @return a copy of the list of issuer distinguished names to match, or
* {@code null} if any issuer distinguished name will do.
- * @since Android 1.0
*/
public Collection<Object> getIssuerNames() {
if (issuerNames == null) {
@@ -338,11 +311,9 @@
* <p>
* The CRL must have a number extension with a value greater than or equal
* to the returned value.
- * </p>
- *
+ *
* @return the minimum CRL number or {@code null} if the minimum CRL number
* is not to be checked.
- * @since Android 1.0
*/
public BigInteger getMinCRL() {
return minCRL;
@@ -353,11 +324,9 @@
* <p>
* The CRL must have a number extension with a value less than or equal to
* the returned value.
- * </p>
- *
+ *
* @return the maximum CRL number or null if the maximum CRL number is not
* checked.
- * @since Android 1.0
*/
public BigInteger getMaxCRL() {
return maxCRL;
@@ -368,11 +337,9 @@
* <p>
* The CRL's {@code thisUpdate} value must be equal or before the returned
* date and the {@code nextUpdate} value must be after the returned date.
- * </p>
- *
+ *
* @return the date to search for valid CRL's or {@code null} if the date is
* not checked.
- * @since Android 1.0
*/
public Date getDateAndTime() {
if (dateAndTime == -1) {
@@ -384,9 +351,8 @@
/**
* Returns the certificate hint to find CRLs. It's not a criterion but may
* help finding relevant CRLs.
- *
+ *
* @return the certificate hint or {@code null} if none set.
- * @since Android 1.0
*/
public X509Certificate getCertificateChecking() {
return certificateChecking;
@@ -394,12 +360,11 @@
/**
* Returns a string representation of this {@code X509CRLSelector} instance.
- *
+ *
* @return a string representation of this {@code X509CRLSelector} instance.
- * @since Android 1.0
*/
public String toString() {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
result.append("X509CRLSelector:\n["); //$NON-NLS-1$
if (issuerNames != null) {
result.append("\n IssuerNames:\n ["); //$NON-NLS-1$
@@ -429,12 +394,11 @@
/**
* Returns whether the specified CRL matches all the criteria collected in
* this instance.
- *
+ *
* @param crl
* the CRL to check.
* @return {@code true} if the CRL matches all the criteria, otherwise
* {@code false}.
- * @since Android 1.0
*/
public boolean match(CRL crl) {
if (!(crl instanceof X509CRL)) {
@@ -482,19 +446,20 @@
/**
* Clones this {@code X509CRL} instance.
- *
+ *
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone() {
- X509CRLSelector result = new X509CRLSelector();
- if (issuerNames != null) {
- result.issuerNames = new ArrayList<String>(issuerNames);
- }
- result.minCRL = minCRL;
- result.maxCRL = maxCRL;
- result.dateAndTime = dateAndTime;
- result.certificateChecking = certificateChecking;
+ X509CRLSelector result;
+
+ try {
+ result = (X509CRLSelector) super.clone();
+ if (issuerNames != null) {
+ result.issuerNames = new ArrayList<String>(issuerNames);
+ }
+ } catch (CloneNotSupportedException e) {
+ result = null;
+ }
return result;
}
}
diff --git a/security/src/main/java/java/security/cert/X509CertSelector.java b/security/src/main/java/java/security/cert/X509CertSelector.java
index c6d2e98..e2de95b 100644
--- a/security/src/main/java/java/security/cert/X509CertSelector.java
+++ b/security/src/main/java/java/security/cert/X509CertSelector.java
@@ -49,8 +49,6 @@
/**
* A certificate selector ({@code CertSelector} for selecting {@code
* X509Certificate}s that match the specified criteria.
- *
- * @since Android 1.0
*/
public class X509CertSelector implements CertSelector {
@@ -81,17 +79,14 @@
/**
* Creates a new {@code X509CertSelector}.
- *
- * @since Android 1.0
*/
public X509CertSelector() {}
/**
* Sets the certificate that a matching certificate must be equal to.
- *
+ *
* @param certificate
* the certificate to match, or null to not check this criteria.
- * @since Android 1.0
*/
public void setCertificate(X509Certificate certificate) {
certificateEquals = certificate;
@@ -99,10 +94,9 @@
/**
* Returns the certificate that a matching certificate must be equal to.
- *
+ *
* @return the certificate to match, or null if this criteria is not
* checked.
- * @since Android 1.0
*/
public X509Certificate getCertificate() {
return certificateEquals;
@@ -110,11 +104,10 @@
/**
* Sets the serial number that a certificate must match.
- *
+ *
* @param serialNumber
* the serial number to match, or {@code null} to not check the
* serial number.
- * @since Android 1.0
*/
public void setSerialNumber(BigInteger serialNumber) {
this.serialNumber = serialNumber;
@@ -122,10 +115,9 @@
/**
* Returns the serial number that a certificate must match.
- *
+ *
* @return the serial number to match, or {@code null} if the serial number
* is not to be checked.
- * @since Android 1.0
*/
public BigInteger getSerialNumber() {
return serialNumber;
@@ -133,11 +125,10 @@
/**
* Sets the issuer that a certificate must match.
- *
+ *
* @param issuer
* the issuer to match, or {@code null} if the issuer is not to
* be checked.
- * @since Android 1.0
*/
public void setIssuer(X500Principal issuer) {
this.issuer = issuer;
@@ -147,10 +138,9 @@
/**
* Returns the issuer that a certificate must match.
- *
+ *
* @return the issuer that a certificate must match, or {@code null} if the
* issuer is not to be checked.
- * @since Android 1.0
*/
public X500Principal getIssuer() {
return issuer;
@@ -160,13 +150,12 @@
* <b>Do not use</b>, use {@link #getIssuer()} or
* {@link #getIssuerAsBytes()} instead. Sets the issuer that a certificate
* must match.
- *
+ *
* @param issuerName
* the issuer in a RFC 2253 format string, or {@code null} to not
* check the issuer.
* @throws IOException
* if parsing the issuer fails.
- * @since Android 1.0
*/
public void setIssuer(String issuerName) throws IOException {
if (issuerName == null) {
@@ -188,10 +177,9 @@
* <b>Do not use</b>, use {@link #getIssuer()} or
* {@link #getIssuerAsBytes()} instead. Returns the issuer that a
* certificate must match in a RFC 2253 format string.
- *
+ *
* @return the issuer in a RFC 2253 format string, or {@code null} if the
* issuer is not to be checked.
- * @since Android 1.0
*/
public String getIssuerAsString() {
if (issuer == null) {
@@ -205,13 +193,12 @@
/**
* Sets the issuer that a certificate must match.
- *
+ *
* @param issuerDN
* the distinguished issuer name in ASN.1 DER encoded format, or
* {@code null} to not check the issuer.
* @throws IOException
* if decoding the issuer fail.
- * @since Android 1.0
*/
public void setIssuer(byte[] issuerDN) throws IOException {
if (issuerDN == null) {
@@ -230,12 +217,11 @@
/**
* Returns the issuer that a certificate must match.
- *
+ *
* @return the distinguished issuer name in ASN.1 DER encoded format, or
* {@code null} if the issuer is not to be checked.
* @throws IOException
* if encoding the issuer fails.
- * @since Android 1.0
*/
public byte[] getIssuerAsBytes() throws IOException {
if (issuer == null) {
@@ -251,11 +237,10 @@
/**
* Set the subject that a certificate must match.
- *
+ *
* @param subject
* the subject distinguished name or {@code null} to not check
* the subject.
- * @since Android 1.0
*/
public void setSubject(X500Principal subject) {
this.subject = subject;
@@ -263,10 +248,9 @@
/**
* Returns the subject that a certificate must match.
- *
+ *
* @return the subject distinguished name, or null if the subject is not to
* be checked.
- * @since Android 1.0
*/
public X500Principal getSubject() {
return subject;
@@ -276,13 +260,12 @@
* <b>Do not use</b>, use {@link #setSubject(byte[])} or
* {@link #setSubject(X500Principal)} instead. Returns the subject that a
* certificate must match.
- *
+ *
* @param subjectDN
* the subject distinguished name in RFC 2253 format or {@code
* null} to not check the subject.
* @throws IOException
* if decoding the subject fails.
- * @since Android 1.0
*/
public void setSubject(String subjectDN) throws IOException {
if (subjectDN == null) {
@@ -300,10 +283,9 @@
* <b>Do not use</b>, use {@link #getSubject()} or
* {@link #getSubjectAsBytes()} instead. Returns the subject that a
* certificate must match.
- *
+ *
* @return the subject distinguished name in RFC 2253 format, or {@code
* null} if the subject is not to be checked.
- * @since Android 1.0
*/
public String getSubjectAsString() {
if (subject == null) {
@@ -314,13 +296,12 @@
/**
* Sets the subject that a certificate must match.
- *
+ *
* @param subjectDN
* the subject distinguished name in ASN.1 DER format, or {@code
* null} to not check the subject.
* @throws IOException
* if decoding the subject fails.
- * @since Android 1.0
*/
public void setSubject(byte[] subjectDN) throws IOException {
if (subjectDN == null) {
@@ -336,12 +317,11 @@
/**
* Returns the subject that a certificate must match.
- *
+ *
* @return the subject distinguished name in ASN.1 DER format, or {@code
* null} if the subject is not to be checked.
* @throws IOException
* if encoding the subject fails.
- * @since Android 1.0
*/
public byte[] getSubjectAsBytes() throws IOException {
if (subject == null) {
@@ -354,12 +334,10 @@
* Sets the criterion for the {@literal SubjectKeyIdentifier} extension.
* <p>
* The {@code subjectKeyIdentifier} should be a single DER encoded value.
- * </p>
- *
+ *
* @param subjectKeyIdentifier
* the subject key identifier or {@code null} to disable this
* check.
- * @since Android 1.0
*/
public void setSubjectKeyIdentifier(byte[] subjectKeyIdentifier) {
if (subjectKeyIdentifier == null) {
@@ -373,10 +351,9 @@
/**
* Returns the criterion for the {@literal SubjectKeyIdentifier} extension.
- *
+ *
* @return the subject key identifier or {@code null} if it is not to be
* checked.
- * @since Android 1.0
*/
public byte[] getSubjectKeyIdentifier() {
if (subjectKeyIdentifier == null) {
@@ -389,11 +366,10 @@
/**
* Sets the criterion for the {@literal AuthorityKeyIdentifier} extension.
- *
+ *
* @param authorityKeyIdentifier
* the authority key identifier, or {@code null} to disable this
* check.
- * @since Android 1.0
*/
public void setAuthorityKeyIdentifier(byte[] authorityKeyIdentifier) {
if (authorityKeyIdentifier == null) {
@@ -409,10 +385,9 @@
/**
* Returns the criterion for the {@literal AuthorityKeyIdentifier}
* extension.
- *
+ *
* @return the authority key identifier, or {@code null} if it is not to be
* checked.
- * @since Android 1.0
*/
public byte[] getAuthorityKeyIdentifier() {
if (authorityKeyIdentifier == null) {
@@ -427,10 +402,8 @@
* Sets the criterion for the validity date of the certificate.
* <p>
* The certificate must be valid at the specified date.
- * </p>
* @param certificateValid
* the validity date or {@code null} to not check the date.
- * @since Android 1.0
*/
public void setCertificateValid(Date certificateValid) {
this.certificateValid = (certificateValid == null)
@@ -440,10 +413,9 @@
/**
* Returns the criterion for the validity date of the certificate.
- *
+ *
* @return the validity date or {@code null} if the date is not to be
* checked.
- * @since Android 1.0
*/
public Date getCertificateValid() {
return (certificateValid == null)
@@ -455,11 +427,9 @@
* Sets the criterion for the validity date of the private key.
* <p>
* The private key must be valid at the specified date.
- * </p>
- *
+ *
* @param privateKeyValid
* the validity date or {@code null} to not check the date.
- * @since Android 1.0
*/
public void setPrivateKeyValid(Date privateKeyValid) {
if (privateKeyValid == null) {
@@ -473,11 +443,9 @@
* Returns the criterion for the validity date of the private key.
* <p>
* The private key must be valid at the specified date.
- * </p>
- *
+ *
* @return the validity date or {@code null} if the date is not to be
* checked.
- * @since Android 1.0
*/
public Date getPrivateKeyValid() {
if (privateKeyValid != null) {
@@ -512,14 +480,12 @@
* <p>
* The certificate must contain a subject public key with the algorithm
* specified.
- * </p>
- *
+ *
* @param oid
* the OID (object identifier) of the signature algorithm or
* {@code null} to not check the OID.
* @throws IOException
* if the specified object identifier is invalid.
- * @since Android 1.0
*/
public void setSubjectPublicKeyAlgID(String oid) throws IOException {
if (oid == null) {
@@ -532,10 +498,9 @@
/**
* Returns the criterion for the subject public key signature algorithm.
- *
+ *
* @return the OID (object identifier) or the signature algorithm or {@code
* null} if it's not to be checked.
- * @since Android 1.0
*/
public String getSubjectPublicKeyAlgID() {
return subjectPublicKeyAlgID;
@@ -543,10 +508,9 @@
/**
* Sets the criterion for the subject public key.
- *
+ *
* @param key
* the subject public key or {@code null} to not check the key.
- * @since Android 1.0
*/
public void setSubjectPublicKey(PublicKey key) {
subjectPublicKey = (key == null) ? null : key.getEncoded();
@@ -555,13 +519,12 @@
/**
* Sets the criterion for the subject public key.
- *
+ *
* @param key
* the subject public key in ASN.1 DER encoded format or {@code null} to
* not check the key.
* @throws IOException
* if decoding the the public key fails.
- * @since Android 1.0
*/
public void setSubjectPublicKey(byte[] key) throws IOException {
if (key == null) {
@@ -578,10 +541,9 @@
/**
* Returns the criterion for the subject public key.
- *
+ *
* @return the subject public key or {@code null} if the key is not to be
* checked.
- * @since Android 1.0
*/
public PublicKey getSubjectPublicKey() {
return subjectPublicKeyImpl;
@@ -589,12 +551,11 @@
/**
* Sets the criterion for the {@literal KeyUsage} extension.
- *
+ *
* @param keyUsage
* the boolean array in the format as returned by
* {@link X509Certificate#getKeyUsage()}, or {@code null} to not
* check the key usage.
- * @since Android 1.0
*/
public void setKeyUsage(boolean[] keyUsage) {
if (keyUsage == null) {
@@ -607,11 +568,10 @@
/**
* Returns the criterion for the {@literal KeyUsage} extension.
- *
+ *
* @return the boolean array in the format as returned by
* {@link X509Certificate#getKeyUsage()}, or {@code null} if the key
* usage is not to be checked.
- * @since Android 1.0
*/
public boolean[] getKeyUsage() {
if (keyUsage == null) {
@@ -624,12 +584,11 @@
/**
* Sets the criterion for the {@literal ExtendedKeyUsage} extension.
- *
+ *
* @param keyUsage
* the set of key usage OIDs, or {@code null} to not check it.
* @throws IOException
* if one of the OIDs is invalid.
- * @since Android 1.0
*/
public void setExtendedKeyUsage(Set<String> keyUsage)
throws IOException {
@@ -649,10 +608,9 @@
/**
* Returns the criterion for the {@literal ExtendedKeyUsage} extension.
- *
+ *
* @return the set of key usage OIDs, or {@code null} if it's not to be
* checked.
- * @since Android 1.0
*/
public Set<String> getExtendedKeyUsage() {
return extendedKeyUsage;
@@ -662,15 +620,12 @@
* Sets the flag for the matching behavior for subject alternative names.
* <p>
* The flag indicates whether a certificate must contain all or at least one
- * of the subject alternative names specified by
- * {@link #setSubjectAlternativeNames} or {@link #addSubjectAlternativeName}
- * .
- * </p>
- *
+ * of the subject alternative names specified by {@link
+ * #setSubjectAlternativeNames} or {@link #addSubjectAlternativeName}.
+ *
* @param matchAllNames
* {@code true} if a certificate must contain all of the
* specified subject alternative names, otherwise {@code false}.
- * @since Android 1.0
*/
public void setMatchAllSubjectAltNames(boolean matchAllNames) {
this.matchAllNames = matchAllNames;
@@ -680,14 +635,11 @@
* Returns the flag for the matching behavior for subject alternative names.
* <p>
* The flag indicates whether a certificate must contain all or at least one
- * of the subject alternative names specified by
- * {@link #setSubjectAlternativeNames} or {@link #addSubjectAlternativeName}
- * .
- * </p>
- *
+ * of the subject alternative names specified by {@link
+ * #setSubjectAlternativeNames} or {@link #addSubjectAlternativeName}.
+ *
* @return {@code true} if a certificate must contain all of the specified
* subject alternative names, otherwise {@code false}.
- * @since Android 1.0
*/
public boolean getMatchAllSubjectAltNames() {
return matchAllNames;
@@ -699,20 +651,17 @@
* the certificate must contain all or at least one of the specified subject
* alternative names. The behavior is specified by
* {@link #getMatchAllSubjectAltNames}.
- * </p>
* <p>
* The specified parameter {@code names} is a collection with an entry for
* each name to be included in the criterion. The name is specified as a
* {@code List}, the first entry must be an {@code Integer} specifying the
* name type (0-8), the second entry must be a {@code String} or a byte
* array specifying the name (in string or ASN.1 DER encoded form)
- * </p>
- *
+ *
* @param names
* the names collection or {@code null} to not perform this check.
* @throws IOException
* if the decoding of a name fails.
- * @since Android 1.0
*/
public void setSubjectAlternativeNames(Collection<List<?>> names)
throws IOException {
@@ -737,14 +686,13 @@
/**
* Adds a subject alternative name to the respective criterion.
- *
+ *
* @param tag
* the type of the name
* @param name
* the name in string format.
* @throws IOException
* if parsing the name fails.
- * @since Android 1.0
*/
public void addSubjectAlternativeName(int tag, String name)
throws IOException {
@@ -761,14 +709,13 @@
/**
* Adds a subject alternative name to the respective criterion.
- *
+ *
* @param tag
* the type of the name.
* @param name
* the name in ASN.1 DER encoded form.
* @throws IOException
* if the decoding of the name fails.
- * @since Android 1.0
*/
public void addSubjectAlternativeName(int tag, byte[] name)
throws IOException {
@@ -789,16 +736,13 @@
* the certificate must contain all or at least one of the specified subject
* alternative names. The behavior is specified by
* {@link #getMatchAllSubjectAltNames}.
- * </p>
* <p>
* The subject alternative names is a collection with an entry for each name
* included in the criterion. The name is specified as a {@code List}, the
* first entry is an {@code Integer} specifying the name type (0-8), the
* second entry is byte array specifying the name in ASN.1 DER encoded form)
- * </p>
- *
+ *
* @return the names collection or {@code null} if none specified.
- * @since Android 1.0
*/
public Collection<List<?>> getSubjectAlternativeNames() {
if (subjectAltNames == null) {
@@ -830,24 +774,23 @@
* <p>
* The certificate must constraint subject and subject alternative names
* that match the specified name constraints.
- * </p>
* <p>
* The name constraints in ASN.1:
- *
+ *
* <pre>
* NameConstraints ::= SEQUENCE {
* permittedSubtrees [0] GeneralSubtrees OPTIONAL,
* excludedSubtrees [1] GeneralSubtrees OPTIONAL }
- *
+ *
* GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
- *
+ *
* GeneralSubtree ::= SEQUENCE {
* base GeneralName,
* minimum [0] BaseDistance DEFAULT 0,
* maximum [1] BaseDistance OPTIONAL }
- *
+ *
* BaseDistance ::= INTEGER (0..MAX)
- *
+ *
* GeneralName ::= CHOICE {
* otherName [0] OtherName,
* rfc822Name [1] IA5String,
@@ -858,17 +801,14 @@
* uniformResourceIdentifier [6] IA5String,
* iPAddress [7] OCTET STRING,
* registeredID [8] OBJECT IDENTIFIER}
- *
+ *
* </pre>
- *
- * </p>
- *
+ *
* @param bytes
* the name constraints in ASN.1 DER encoded format, or null to
* not check any constraints.
* @throws IOException
* if decoding the name constraints fail.
- * @since Android 1.0
*/
public void setNameConstraints(byte[] bytes) throws IOException {
this.nameConstraints = (bytes == null)
@@ -878,10 +818,9 @@
/**
* Returns the criterion for the name constraints.
- *
+ *
* @return the name constraints or {@code null} if none specified.
* @see #setNameConstraints
- * @since Android 1.0
*/
public byte[] getNameConstraints() {
return (nameConstraints == null)
@@ -896,11 +835,9 @@
* include a basic constraints extension with a path length of a least that
* value. A value of {@code -2} indicates that only end-entity certificates
* are accepted. A value of {@code -1} indicates that no check is done.
- * </p>
- *
+ *
* @param pathLen
* the value specifying the criterion.
- * @since Android 1.0
* @throws IllegalArgumentException
* if {@code pathLen} is less than {@code -2}.
*/
@@ -918,10 +855,8 @@
* include a basic constraints extension with a path length of a least that
* value. A value of {@code -2} indicates that only end-entity certificates
* are accepted. A value of {@code -1} indicates that no check is done.
- * </p>
- *
+ *
* @return the value of the criterion.
- * @since Android 1.0
*/
public int getBasicConstraints() {
return pathLen;
@@ -933,14 +868,12 @@
* The certificate must have at least one of the specified certificate
* policy extensions. For an empty set the certificate must have at least
* some policies in its policy extension.
- * </p>
- *
+ *
* @param policies
* the certificate policy OIDs, an empty set, or {@code null} to
* not perform this check.
* @throws IOException
* if parsing the specified OIDs fails.
- * @since Android 1.0
*/
public void setPolicy(Set<String> policies) throws IOException {
if (policies == null) {
@@ -963,11 +896,9 @@
* The certificate must have at least one of the certificate policy
* extensions. For an empty set the certificate must have at least some
* policies in its policy extension.
- * </p>
- *
+ *
* @return the certificate policy OIDs, an empty set, or {@code null} if not
* to be checked.
- * @since Android 1.0
*/
public Set<String> getPolicy() {
return policies;
@@ -978,21 +909,18 @@
* <p>
* This allows to specify the complete set of names, a certificate's name
* constraints must permit.
- * </p>
* <p>
* The specified parameter {@code names} is a collection with an entry for
* each name to be included in the criterion. The name is specified as a
* {@code List}, the first entry must be an {@code Integer} specifying the
* name type (0-8), the second entry must be a {@code String} or a byte
* array specifying the name (in string or ASN.1 DER encoded form)
- * </p>
- *
+ *
* @param names
* the names collection or {@code null} to not perform this
* check.
* @throws IOException
* if decoding fails.
- * @since Android 1.0
*/
public void setPathToNames(Collection<List<?>> names)
throws IOException {
@@ -1017,7 +945,7 @@
/**
* Adds a {@literal "pathToName"} to the respective criterion.
- *
+ *
* @param type
* the type of the name.
* @param name
@@ -1025,7 +953,6 @@
* @throws IOException
* if parsing fails.
* @see #setPathToNames
- * @since Android 1.0
*/
public void addPathToName(int type, String name) throws IOException {
GeneralName path_name = new GeneralName(type, name);
@@ -1038,7 +965,7 @@
/**
* Adds a {@literal "pathToName"} to the respective criterion.
- *
+ *
* @param type
* the type of the name
* @param name
@@ -1046,7 +973,6 @@
* @throws IOException
* if decoding fails.
* @see #setPathToNames
- * @since Android 1.0
*/
public void addPathToName(int type, byte[] name) throws IOException {
GeneralName path_name= new GeneralName(type, name);
@@ -1064,10 +990,8 @@
* in the criterion. The name is specified as a {@code List}, the first
* entry is an {@code Integer} specifying the name type (0-8), the second
* entry is a byte array specifying the name in ASN.1 DER encoded form.
- * </p>
- *
+ *
* @return the pathToNames constraint or {@code null} if none specified.
- * @since Android 1.0
*/
public Collection<List<?>> getPathToNames() {
if (pathToNames == null) {
@@ -1085,17 +1009,16 @@
/**
* Returns a string representation of this {@code X509CertSelector}
* instance.
- *
+ *
* @return a string representation of this {@code X509CertSelector}
* instance.
- * @since Android 1.0
*/
public String toString() {
// For convenient reading of the string representation
// all of the fields named according to the rfc 3280
// (http://www.ietf.org/rfc/rfc3280.txt).
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
result.append("X509CertSelector: \n["); //$NON-NLS-1$
if (this.certificateEquals != null) {
result.append("\n certificateEquals: " + certificateEquals); //$NON-NLS-1$
@@ -1210,12 +1133,11 @@
/**
* Returns whether the specified certificate matches all the criteria
* collected in this instance.
- *
+ *
* @param certificate
* the certificate to check.
* @return {@code true} if the certificate matches all the criteria,
* otherwise {@code false}.
- * @since Android 1.0
*/
public boolean match(Certificate certificate) {
if (! (certificate instanceof X509Certificate)) {
@@ -1452,16 +1374,18 @@
/**
* Clones this {@code X509CertSelector} instance.
- *
+ *
* @return the cloned instance.
- * @since Android 1.0
*/
public Object clone() {
- X509CertSelector result = new X509CertSelector();
- result.certificateEquals = this.certificateEquals;
- result.serialNumber = this.serialNumber;
- result.issuer = this.issuer;
- result.subject = this.subject;
+ X509CertSelector result;
+
+ try {
+ result = (X509CertSelector) super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+
if (this.subjectKeyIdentifier != null) {
result.subjectKeyIdentifier =
new byte[this.subjectKeyIdentifier.length];
@@ -1476,9 +1400,6 @@
result.authorityKeyIdentifier, 0,
this.authorityKeyIdentifier.length);
}
- result.certificateValid = this.certificateValid;
- result.subjectPublicKeyAlgID = this.subjectPublicKeyAlgID;
- result.privateKeyValid = this.privateKeyValid;
if (this.subjectPublicKey != null) {
result.subjectPublicKey = new byte[this.subjectPublicKey.length];
System.arraycopy(this.subjectPublicKey, 0, result.subjectPublicKey,
@@ -1492,8 +1413,6 @@
result.extendedKeyUsage = (this.extendedKeyUsage == null)
? null
: new HashSet(this.extendedKeyUsage);
- result.matchAllNames = this.matchAllNames;
- result.pathLen = this.pathLen;
if (this.subjectAltNames != null) {
result.subjectAltNames = new ArrayList[9];
for (int i=0; i<9; i++) {
@@ -1503,15 +1422,12 @@
}
}
}
- result.nameConstraints = this.nameConstraints;
result.policies = (this.policies == null)
? null
: new HashSet(this.policies);
result.pathToNames = (this.pathToNames == null)
? null
: new ArrayList(this.pathToNames);
- result.subjectPublicKeyImpl = this.subjectPublicKeyImpl;
-
return result;
}
}
diff --git a/security/src/main/java/java/security/cert/X509Certificate.java b/security/src/main/java/java/security/cert/X509Certificate.java
index 9e10077..e49901c 100644
--- a/security/src/main/java/java/security/cert/X509Certificate.java
+++ b/security/src/main/java/java/security/cert/X509Certificate.java
@@ -33,7 +33,6 @@
* <p>
* This represents a standard way for accessing the attributes of X.509
* certificates.
- * </p>
* <p>
* The basic X.509 v3 format described in ASN.1:
*
@@ -59,16 +58,12 @@
* -- If present, version must be v3
* }
* </pre>
- * </p>
* <p>
* For more information consult RFC 2459
* "Internet X.509 Public Key Infrastructure Certificate and CRL Profile" at <a
* href
* ="http://www.ietf.org/rfc/rfc2459.txt">http://www.ietf.org/rfc/rfc2459.txt
* </a> .
- * </p>
- *
- * @since Android 1.0
*/
public abstract class X509Certificate
extends Certificate implements X509Extension {
@@ -77,8 +72,6 @@
/**
* Creates a new {@code X509Certificate}.
- *
- * @since Android 1.0
*/
protected X509Certificate() {
super("X.509"); //$NON-NLS-1$
@@ -101,13 +94,10 @@
* generalTime GeneralizedTime }
* </pre>
*
- * </p>
- *
* @throws CertificateExpiredException
* if the certificate has expired.
* @throws CertificateNotYetValidException
* if the certificate is not yet valid.
- * @since Android 1.0
*/
public abstract void checkValidity()
throws CertificateExpiredException, CertificateNotYetValidException;
@@ -122,7 +112,6 @@
* @throws CertificateNotYetValidException
* if the certificate is not yet valid.
* @see #checkValidity()
- * @since Android 1.0
*/
public abstract void checkValidity(Date date)
throws CertificateExpiredException, CertificateNotYetValidException;
@@ -136,10 +125,7 @@
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
* </pre>
*
- * </p>
- *
* @return the version number.
- * @since Android 1.0
*/
public abstract int getVersion();
@@ -152,10 +138,7 @@
* CertificateSerialNumber ::= INTEGER
* </pre>
*
- * </p>
- *
* @return the serial number.
- * @since Android 1.0
*/
public abstract BigInteger getSerialNumber();
@@ -184,12 +167,10 @@
* AttributeValue ::= ANY DEFINED BY AttributeType
* </pre>
*
- * </p>
* <b>replaced by:</b> {@link #getIssuerX500Principal()}.
*
* @return the {@code issuer} as an implementation specific {@code
* Principal}.
- * @since Android 1.0
*/
public abstract Principal getIssuerDN() ;
@@ -198,7 +179,6 @@
* X500Principal}.
*
* @return the {@code issuer} (issuer distinguished name).
- * @since Android 1.0
*/
public X500Principal getIssuerX500Principal() {
@@ -243,13 +223,10 @@
* AttributeValue ::= ANY DEFINED BY AttributeType
* </pre>
*
- * </p>
* <p>
* <b>replaced by:</b> {@link #getSubjectX500Principal()}.
- * </p>
- *
+ *
* @return the {@code subject} (subject distinguished name).
- * @since Android 1.0
*/
public abstract Principal getSubjectDN();
@@ -258,7 +235,6 @@
* X500Principal}.
*
* @return the {@code subject} (subject distinguished name)
- * @since Android 1.0
*/
public X500Principal getSubjectX500Principal() {
@@ -283,7 +259,6 @@
* certificate.
*
* @return the start of the validity period.
- * @since Android 1.0
*/
public abstract Date getNotBefore();
@@ -292,7 +267,6 @@
* certificate.
*
* @return the end of the validity period.
- * @since Android 1.0
*/
public abstract Date getNotAfter();
@@ -303,7 +277,6 @@
* @return the DER-encoded certificate information.
* @throws CertificateEncodingException
* if an error occurs in encoding
- * @since Android 1.0
*/
public abstract byte[] getTBSCertificate()
throws CertificateEncodingException;
@@ -312,7 +285,6 @@
* Returns the raw signature bits from the certificate.
*
* @return the raw signature bits from the certificate.
- * @since Android 1.0
*/
public abstract byte[] getSignature();
@@ -320,7 +292,6 @@
* Returns the name of the algorithm for the certificate signature.
*
* @return the signature algorithm name.
- * @since Android 1.0
*/
public abstract String getSigAlgName();
@@ -328,7 +299,6 @@
* Returns the OID of the signature algorithm from the certificate.
*
* @return the OID of the signature algorithm.
- * @since Android 1.0
*/
public abstract String getSigAlgOID();
@@ -337,7 +307,6 @@
*
* @return the parameters of the signature algorithm, or {@code null} if
* none are used.
- * @since Android 1.0
*/
public abstract byte[] getSigAlgParams();
@@ -346,7 +315,6 @@
*
* @return the {@code issuerUniqueID} or {@code null} if there's none in the
* certificate.
- * @since Android 1.0
*/
public abstract boolean[] getIssuerUniqueID();
@@ -355,7 +323,6 @@
*
* @return the {@code subjectUniqueID} or null if there's none in the
* certificate.
- * @since Android 1.0
*/
public abstract boolean[] getSubjectUniqueID();
@@ -378,11 +345,8 @@
*
* </pre>
*
- * </p>
- *
* @return the {@code KeyUsage} extension or {@code null} if there's none in
* the certificate.
- * @since Android 1.0
*/
public abstract boolean[] getKeyUsage();
@@ -394,7 +358,6 @@
* in the certificate.
* @throws CertificateParsingException
* if the extension decoding fails.
- * @since Android 1.0
*/
public List<String> getExtendedKeyUsage()
throws CertificateParsingException {
@@ -408,7 +371,6 @@
* @return the path length of the certificate constraints if the extension
* is present or {@code -1} if the extension is not present. {@code
* Integer.MAX_VALUE} if there's not limit.
- * @since Android 1.0
*/
public abstract int getBasicConstraints();
@@ -436,13 +398,10 @@
*
* </pre>
*
- * </p>
- *
* @return the subject alternative names or {@code null} if there are none
* in the certificate.
* @throws CertificateParsingException
* if decoding of the extension fails.
- * @since Android 1.0
*/
public Collection<List<?>> getSubjectAlternativeNames()
throws CertificateParsingException {
@@ -473,13 +432,10 @@
*
* </pre>
*
- * </p>
- *
* @return the issuer alternative names of {@code null} if there are none in
* the certificate.
* @throws CertificateParsingException
* if decoding of the extension fails.
- * @since Android 1.0
*/
public Collection<List<?>> getIssuerAlternativeNames()
throws CertificateParsingException {
diff --git a/security/src/main/java/java/security/cert/X509Extension.java b/security/src/main/java/java/security/cert/X509Extension.java
index cc8648b..1543f3d 100644
--- a/security/src/main/java/java/security/cert/X509Extension.java
+++ b/security/src/main/java/java/security/cert/X509Extension.java
@@ -21,8 +21,6 @@
/**
* The interface specifying an X.509 Certificate or CRL extension.
- *
- * @since Android 1.0
*/
public interface X509Extension {
@@ -33,7 +31,6 @@
* @return the set of extension OIDs marked as CRITIAL, an empty set if none
* are marked as CRITICAL, or {@code null} if no extensions are
* present.
- * @since Android 1.0
*/
public Set<String> getCriticalExtensionOIDs();
@@ -45,7 +42,6 @@
* the object identifier to get the extension value for.
* @return the extension value as DER-encoded OCTET string, or {@code null}
* if no extension for the specified OID can be found.
- * @since Android 1.0
*/
public byte[] getExtensionValue(String oid);
@@ -56,7 +52,6 @@
* @return the set of extension OIDs marked as NON-CRITIAL, an empty set if
* none are marked as NON-.CRITICAL, or {@code null} if no
* extensions are present.
- * @since Android 1.0
*/
public Set<String> getNonCriticalExtensionOIDs();
@@ -66,7 +61,6 @@
*
* @return {@code true} if an unsupported CRITICAL extension is present,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean hasUnsupportedCriticalExtension();
}
diff --git a/security/src/main/java/java/security/interfaces/DSAKey.java b/security/src/main/java/java/security/interfaces/DSAKey.java
index 1362bff..ac9aade 100644
--- a/security/src/main/java/java/security/interfaces/DSAKey.java
+++ b/security/src/main/java/java/security/interfaces/DSAKey.java
@@ -21,8 +21,6 @@
/**
* The base interface for Digital Signature Algorithm (DSA) public or private
* keys.
- *
- * @since Android 1.0
*/
public interface DSAKey {
@@ -30,8 +28,7 @@
* Returns the DSA key parameters.
*
* @return the DSA key parameters.
- * @since Android 1.0
*/
public DSAParams getParams();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/DSAKeyPairGenerator.java b/security/src/main/java/java/security/interfaces/DSAKeyPairGenerator.java
index 4b89c6a..b7b5480 100644
--- a/security/src/main/java/java/security/interfaces/DSAKeyPairGenerator.java
+++ b/security/src/main/java/java/security/interfaces/DSAKeyPairGenerator.java
@@ -22,8 +22,6 @@
/**
* The interface for key generators that can generate DSA key pairs.
- *
- * @since Android 1.0
*/
public interface DSAKeyPairGenerator {
@@ -38,7 +36,6 @@
* @throws InvalidParameterException
* if the specified parameter values are {@code null} or
* invalid.
- * @since Android 1.0
*/
public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException;
@@ -53,7 +50,6 @@
* it will use the pre-calculated values for the specified modulus
* length. Default parameters are available for modulus lengths of 512 and 1024
* bits.
- * </p>
*
* @param modlen
* the length of the modulus in bits.
@@ -65,8 +61,7 @@
* if the specified modulus length is not valid, or if there are
* no pre-calculated values and {@code genParams} is {@code
* false}.
- * @since Android 1.0
*/
public void initialize(int modlen, boolean genParams, SecureRandom random)
throws InvalidParameterException;
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/DSAParams.java b/security/src/main/java/java/security/interfaces/DSAParams.java
index 0483da2..62f2d00 100644
--- a/security/src/main/java/java/security/interfaces/DSAParams.java
+++ b/security/src/main/java/java/security/interfaces/DSAParams.java
@@ -21,8 +21,6 @@
/**
* The interface for Digital Signature Algorithm (DSA) specific parameters.
- *
- * @since Android 1.0
*/
public interface DSAParams {
@@ -30,7 +28,6 @@
* Returns the base ({@code g}) value.
*
* @return the base ({@code g}) value.
- * @since Android 1.0
*/
public BigInteger getG();
@@ -38,7 +35,6 @@
* Returns the prime ({@code p}) value.
*
* @return the prime ({@code p}) value.
- * @since Android 1.0
*/
public BigInteger getP();
@@ -46,7 +42,6 @@
* Returns the subprime ({@code q} value.
*
* @return the subprime ({@code q} value.
- * @since Android 1.0
*/
public BigInteger getQ();
diff --git a/security/src/main/java/java/security/interfaces/DSAPrivateKey.java b/security/src/main/java/java/security/interfaces/DSAPrivateKey.java
index e2592ca..6419440 100644
--- a/security/src/main/java/java/security/interfaces/DSAPrivateKey.java
+++ b/security/src/main/java/java/security/interfaces/DSAPrivateKey.java
@@ -22,15 +22,11 @@
/**
* The interface for a Digital Signature Algorithm (DSA) private key.
- *
- * @since Android 1.0
*/
public interface DSAPrivateKey extends DSAKey, PrivateKey {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = 7776497482533790279L;
@@ -38,8 +34,7 @@
* Returns the private key value {@code x}.
*
* @return the private key value {@code x}.
- * @since Android 1.0
*/
public BigInteger getX();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/DSAPublicKey.java b/security/src/main/java/java/security/interfaces/DSAPublicKey.java
index ccb985e..9642bf1 100644
--- a/security/src/main/java/java/security/interfaces/DSAPublicKey.java
+++ b/security/src/main/java/java/security/interfaces/DSAPublicKey.java
@@ -22,15 +22,11 @@
/**
* The interface for a Digital Signature Algorithm (DSA) public key.
- *
- * @since Android 1.0
*/
public interface DSAPublicKey extends DSAKey, PublicKey {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = 1234526332779022332L;
@@ -38,8 +34,7 @@
* Returns the public key value {@code y}.
*
* @return the public key value {@code y}.
- * @since Android 1.0
*/
public BigInteger getY();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/ECKey.java b/security/src/main/java/java/security/interfaces/ECKey.java
index 9f5d254..5469392 100644
--- a/security/src/main/java/java/security/interfaces/ECKey.java
+++ b/security/src/main/java/java/security/interfaces/ECKey.java
@@ -21,8 +21,6 @@
/**
* The base interface for Elliptic Curve (EC) public or private keys.
- *
- * @since Android 1.0
*/
public interface ECKey {
@@ -30,7 +28,6 @@
* Returns the EC key parameters.
*
* @return the EC key parameters.
- * @since Android 1.0
*/
public ECParameterSpec getParams();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/ECPrivateKey.java b/security/src/main/java/java/security/interfaces/ECPrivateKey.java
index 74ef4c2..254d2a6 100644
--- a/security/src/main/java/java/security/interfaces/ECPrivateKey.java
+++ b/security/src/main/java/java/security/interfaces/ECPrivateKey.java
@@ -22,15 +22,11 @@
/**
* The interface for an Elliptic Curve (EC) private key.
- *
- * @since Android 1.0
*/
public interface ECPrivateKey extends PrivateKey, ECKey {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = -7896394956925609184L;
@@ -38,7 +34,6 @@
* Returns the private value {@code S}.
*
* @return the private value {@code S}.
- * @since Android 1.0
*/
public BigInteger getS();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/ECPublicKey.java b/security/src/main/java/java/security/interfaces/ECPublicKey.java
index 063dfe9..8ad97fc 100644
--- a/security/src/main/java/java/security/interfaces/ECPublicKey.java
+++ b/security/src/main/java/java/security/interfaces/ECPublicKey.java
@@ -22,15 +22,11 @@
/**
* The interface for an Elliptic Curve (EC) public key.
- *
- * @since Android 1.0
*/
public interface ECPublicKey extends PublicKey, ECKey {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = -3314988629879632826L;
@@ -38,7 +34,6 @@
* Returns the public point {@code W} on an elliptic curve (EC).
*
* @return the public point {@code W} on an elliptic curve (EC).
- * @since Android 1.0
*/
public ECPoint getW();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/RSAKey.java b/security/src/main/java/java/security/interfaces/RSAKey.java
index bc0877e..2c9e6c1 100644
--- a/security/src/main/java/java/security/interfaces/RSAKey.java
+++ b/security/src/main/java/java/security/interfaces/RSAKey.java
@@ -21,8 +21,6 @@
/**
* The base interface for PKCS#1 RSA public and private keys.
- *
- * @since Android 1.0
*/
public interface RSAKey {
@@ -30,7 +28,6 @@
* Returns the modulus.
*
* @return the modulus.
- * @since Android 1.0
*/
public BigInteger getModulus();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/security/src/main/java/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
index c5e86c3..d8aa1bf 100644
--- a/security/src/main/java/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
+++ b/security/src/main/java/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java
@@ -24,15 +24,11 @@
* The interface for a Multi-Prime RSA private key. Specified by <a
* href="http://www.rsa.com/rsalabs/node.asp?id=2125">PKCS #1 v2.0 Amendment 1:
* Multi-Prime RSA</a>.
- *
- * @since Android 1.0
*/
public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey {
/**
* the serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = 618058533534628008L;
@@ -40,7 +36,6 @@
* Returns the CRT coefficient, {@code q^-1 mod p}.
*
* @return the CRT coefficient.
- * @since Android 1.0
*/
public BigInteger getCrtCoefficient();
@@ -49,7 +44,6 @@
*
* @return the information for the additional primes, or {@code null} if
* there are only the two primes ({@code p, q}),
- * @since Android 1.0
*/
public RSAOtherPrimeInfo[] getOtherPrimeInfo();
@@ -57,7 +51,6 @@
* Returns the prime factor {@code p} of {@code n}.
*
* @return the prime factor {@code p} of {@code n}.
- * @since Android 1.0
*/
public BigInteger getPrimeP();
@@ -65,7 +58,6 @@
* Returns the prime factor {@code q} of {@code n}.
*
* @return the prime factor {@code q} of {@code n}.
- * @since Android 1.0
*/
public BigInteger getPrimeQ();
@@ -73,7 +65,6 @@
* Returns the CRT exponent of the prime {@code p}.
*
* @return the CRT exponent of the prime {@code p}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentP();
@@ -81,7 +72,6 @@
* Returns the CRT exponent of the prime {@code q}.
*
* @return the CRT exponent of the prime {@code q}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentQ();
@@ -89,7 +79,6 @@
* Returns the public exponent {@code e}.
*
* @return the public exponent {@code e}.
- * @since Android 1.0
*/
public BigInteger getPublicExponent();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/RSAPrivateCrtKey.java b/security/src/main/java/java/security/interfaces/RSAPrivateCrtKey.java
index 48d70ce..a670491 100644
--- a/security/src/main/java/java/security/interfaces/RSAPrivateCrtKey.java
+++ b/security/src/main/java/java/security/interfaces/RSAPrivateCrtKey.java
@@ -21,15 +21,11 @@
/**
* The interface for a PKCS#1 RSA private key using CRT information values.
- *
- * @since Android 1.0
*/
public interface RSAPrivateCrtKey extends RSAPrivateKey {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = -5682214253527700368L;
@@ -37,7 +33,6 @@
* Returns the CRT coefficient, {@code q^-1 mod p}.
*
* @return the CRT coefficient.
- * @since Android 1.0
*/
public BigInteger getCrtCoefficient();
@@ -45,7 +40,6 @@
* Returns the prime factor {@code p} of {@code n}.
*
* @return the prime factor {@code p} of {@code n}.
- * @since Android 1.0
*/
public BigInteger getPrimeP();
@@ -53,7 +47,6 @@
* Returns the prime factor {@code q} of {@code n}.
*
* @return the prime factor {@code q} of {@code n}.
- * @since Android 1.0
*/
public BigInteger getPrimeQ();
@@ -61,7 +54,6 @@
* Returns the CRT exponent of the primet {@code p}.
*
* @return the CRT exponent of the prime {@code p}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentP();
@@ -69,7 +61,6 @@
* Returns the CRT exponent of the prime {@code q}.
*
* @return the CRT exponent of the prime {@code q}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentQ();
@@ -77,7 +68,6 @@
* Returns the public exponent {@code e}.
*
* @return the public exponent {@code e}.
- * @since Android 1.0
*/
public BigInteger getPublicExponent();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/RSAPrivateKey.java b/security/src/main/java/java/security/interfaces/RSAPrivateKey.java
index 041a1e3..0da15e9 100644
--- a/security/src/main/java/java/security/interfaces/RSAPrivateKey.java
+++ b/security/src/main/java/java/security/interfaces/RSAPrivateKey.java
@@ -22,15 +22,11 @@
/**
* The interface for an PKCS#1 RSA private key.
- *
- * @since Android 1.0
*/
public interface RSAPrivateKey extends PrivateKey, RSAKey {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = 5187144804936595022L;
@@ -38,7 +34,6 @@
* Returns the private exponent {@code d}.
*
* @return the private exponent {@code d}.
- * @since Android 1.0
*/
public BigInteger getPrivateExponent();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/interfaces/RSAPublicKey.java b/security/src/main/java/java/security/interfaces/RSAPublicKey.java
index b13b1aa..379351f 100644
--- a/security/src/main/java/java/security/interfaces/RSAPublicKey.java
+++ b/security/src/main/java/java/security/interfaces/RSAPublicKey.java
@@ -22,15 +22,11 @@
/**
* The interface for a PKCS#1 RSA public key.
- *
- * @since Android 1.0
*/
public interface RSAPublicKey extends PublicKey, RSAKey {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
public static final long serialVersionUID = -8727434096241101194L;
@@ -38,8 +34,7 @@
* Returns the public exponent {@code e}.
*
* @return the public exponent {@code e}.
- * @since Android 1.0
*/
public BigInteger getPublicExponent();
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/spec/AlgorithmParameterSpec.java b/security/src/main/java/java/security/spec/AlgorithmParameterSpec.java
index 32c7a3a..0cbba76 100644
--- a/security/src/main/java/java/security/spec/AlgorithmParameterSpec.java
+++ b/security/src/main/java/java/security/spec/AlgorithmParameterSpec.java
@@ -20,8 +20,6 @@
/**
* The marker interface for algorithm parameter specifications. The purpose is
* to group parameter specifications for algorithms.
- *
- * @since Android 1.0
*/
public interface AlgorithmParameterSpec {
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/spec/DSAParameterSpec.java b/security/src/main/java/java/security/spec/DSAParameterSpec.java
index 5465b5b..e23a682 100644
--- a/security/src/main/java/java/security/spec/DSAParameterSpec.java
+++ b/security/src/main/java/java/security/spec/DSAParameterSpec.java
@@ -22,8 +22,6 @@
/**
* The parameter specification used with the Digital Signature Algorithm (DSA).
- *
- * @since Android 1.0
*/
public class DSAParameterSpec implements AlgorithmParameterSpec, DSAParams {
// Prime
@@ -43,7 +41,6 @@
* the sub-prime {@code q}.
* @param g
* the base {@code g};
- * @since Android 1.0
*/
public DSAParameterSpec(BigInteger p, BigInteger q, BigInteger g) {
this.p = p;
@@ -55,7 +52,6 @@
* Returns the base {@code g}.
*
* @return the base {@code g}.
- * @since Android 1.0
*/
public BigInteger getG() {
return g;
@@ -65,7 +61,6 @@
* Returns the prime {@code p}.
*
* @return the prime {@code p}.
- * @since Android 1.0
*/
public BigInteger getP() {
return p;
@@ -73,8 +68,8 @@
/**
* Returns the sub-prime {@code q}.
+ *
* @return the sub-prime {@code q}.
- * @since Android 1.0
*/
public BigInteger getQ() {
return q;
diff --git a/security/src/main/java/java/security/spec/DSAPrivateKeySpec.java b/security/src/main/java/java/security/spec/DSAPrivateKeySpec.java
index 3b692c8..6dc12c8 100644
--- a/security/src/main/java/java/security/spec/DSAPrivateKeySpec.java
+++ b/security/src/main/java/java/security/spec/DSAPrivateKeySpec.java
@@ -21,8 +21,6 @@
/**
* The parameters specifying a DSA private key.
- *
- * @since Android 1.0
*/
public class DSAPrivateKeySpec implements KeySpec {
// Private key
@@ -46,7 +44,6 @@
* the sub-prime {@code q}.
* @param g
* the base {@code g}.
- * @since Android 1.0
*/
public DSAPrivateKeySpec(BigInteger x, BigInteger p,
BigInteger q, BigInteger g) {
@@ -60,7 +57,6 @@
* Returns the base {@code g}.
*
* @return the base {@code g}.
- * @since Android 1.0
*/
public BigInteger getG() {
return g;
@@ -70,7 +66,6 @@
* Returns the prime {@code p}.
*
* @return the prime {@code p}.
- * @since Android 1.0
*/
public BigInteger getP() {
return p;
@@ -80,7 +75,6 @@
* Returns the sub-prime {@code q}.
*
* @return the sub-prime {@code q}.
- * @since Android 1.0
*/
public BigInteger getQ() {
return q;
@@ -90,7 +84,6 @@
* Returns the private key {@code x}.
*
* @return the private key {@code x}.
- * @since Android 1.0
*/
public BigInteger getX() {
return x;
diff --git a/security/src/main/java/java/security/spec/DSAPublicKeySpec.java b/security/src/main/java/java/security/spec/DSAPublicKeySpec.java
index 95d1141..af90919 100644
--- a/security/src/main/java/java/security/spec/DSAPublicKeySpec.java
+++ b/security/src/main/java/java/security/spec/DSAPublicKeySpec.java
@@ -21,8 +21,6 @@
/**
* The parameters specifying a DSA public key.
- *
- * @since Android 1.0
*/
public class DSAPublicKeySpec implements KeySpec {
// Public key
@@ -46,7 +44,6 @@
* the sub-prime {@code q}.
* @param g
* the base {@code g}.
- * @since Android 1.0
*/
public DSAPublicKeySpec(BigInteger y, BigInteger p,
BigInteger q, BigInteger g) {
@@ -60,7 +57,6 @@
* Returns the base {@code g}.
*
* @return the base {@code g}.
- * @since Android 1.0
*/
public BigInteger getG() {
return g;
@@ -70,7 +66,6 @@
* Returns the prime {@code p}.
*
* @return the prime {@code p}.
- * @since Android 1.0
*/
public BigInteger getP() {
return p;
@@ -80,7 +75,6 @@
* Returns the sub-prime {@code q}.
*
* @return the sub-prime {@code q}.
- * @since Android 1.0
*/
public BigInteger getQ() {
return q;
@@ -90,7 +84,6 @@
* Returns the public key value {@code y}.
*
* @return the public key value {@code y}.
- * @since Android 1.0
*/
public BigInteger getY() {
return y;
diff --git a/security/src/main/java/java/security/spec/ECField.java b/security/src/main/java/java/security/spec/ECField.java
index 74a5eb8..b4c6be2 100644
--- a/security/src/main/java/java/security/spec/ECField.java
+++ b/security/src/main/java/java/security/spec/ECField.java
@@ -19,8 +19,6 @@
/**
* The base interface for a Finite Field of an Elliptic Curve.
- *
- * @since Android 1.0
*/
public interface ECField {
@@ -28,7 +26,6 @@
* Returns the size of the field (in bits).
*
* @return the size of the field (in bits).
- * @since Android 1.0
*/
int getFieldSize();
}
diff --git a/security/src/main/java/java/security/spec/ECFieldF2m.java b/security/src/main/java/java/security/spec/ECFieldF2m.java
index d68378b..e5a636a 100644
--- a/security/src/main/java/java/security/spec/ECFieldF2m.java
+++ b/security/src/main/java/java/security/spec/ECFieldF2m.java
@@ -25,8 +25,6 @@
/**
* The parameters specifying a <i>characteristic 2 finite field</i> of an
* elliptic curve.
- *
- * @since Android 1.0
*/
public class ECFieldF2m implements ECField {
// Mid terms array length for trinomial basis
@@ -52,7 +50,6 @@
* the exponent {@code m} for the number of elements.
* @throws IllegalArgumentException
* if {@code m <= zero}.
- * @since Android 1.0
*/
public ECFieldF2m(int m) {
this.m = m;
@@ -69,8 +66,7 @@
* <p>
* The reduction polynomial must be either <i>trinomial</i> or
* <i>pentanomial</i>.
- * </p>
- *
+ *
* @param m
* the exponent {@code m} for the number of elements.
* @param rp
@@ -79,7 +75,6 @@
* polynomial.
* @throws IllegalArgumentException
* if {@code m <= zero} or the {@code rp} is invalid.
- * @since Android 1.0
*/
public ECFieldF2m(int m, BigInteger rp) {
this.m = m;
@@ -117,7 +112,6 @@
* <p>
* The reduction polynomial must be either <i>trinomial</i> or
* <i>pentanomial</i>.
- * </p>
*
* @param m
* the exponent {@code m} for the number of elements.
@@ -127,7 +121,6 @@
* @throws IllegalArgumentException
* if {@code m <= zero} or the reduction polynomial is not
* valid.
- * @since Android 1.0
*/
public ECFieldF2m(int m, int[] ks) {
this.m = m;
@@ -182,7 +175,6 @@
* the object to compare to this finite field.
* @return {@code true} if the specified object is equal to this finite field,
* otherwise {@code false}.
- * @since Android 1.0
*/
public boolean equals(Object obj) {
// object equals to itself
@@ -214,7 +206,6 @@
* Returns the size of this finite field (in bits).
*
* @return the size of this finite field (in bits).
- * @since Android 1.0
*/
public int getFieldSize() {
return m;
@@ -225,7 +216,6 @@
* the number of elements.
*
* @return the exponent {@code m} for this finite field
- * @since Android 1.0
*/
public int getM() {
return m;
@@ -238,7 +228,6 @@
* @return a copy of the integer array containing the order of the middle
* term(s) of the reduction polynomial for a polynomial basis or
* {@code null} for a normal basis.
- * @since Android 1.0
*/
public int[] getMidTermsOfReductionPolynomial() {
// Defensively copies private array
@@ -261,7 +250,6 @@
* @return the base of the reduction polynomial with the n-th bit
* corresponding to the n-th coefficient of the reduction polynomial
* for a polynomial basis or {@code null} for a normal basis.
- * @since Android 1.0
*/
public BigInteger getReductionPolynomial() {
return rp;
@@ -271,7 +259,6 @@
* Returns the hashcode value for this finite field.
*
* @return the hashcode value for this finite field.
- * @since Android 1.0
*/
public int hashCode() {
return rp == null ? m : m + rp.hashCode();
diff --git a/security/src/main/java/java/security/spec/ECFieldFp.java b/security/src/main/java/java/security/spec/ECFieldFp.java
index d3f4ee6..b68238d 100644
--- a/security/src/main/java/java/security/spec/ECFieldFp.java
+++ b/security/src/main/java/java/security/spec/ECFieldFp.java
@@ -24,8 +24,6 @@
/**
* The parameters specifying a <i>prime finite field</i> of an
* elliptic curve.
- *
- * @since Android 1.0
*/
public class ECFieldFp implements ECField {
// Prime
@@ -39,7 +37,6 @@
* the prime value {@code p}.
* @throws IllegalArgumentException
* if {@code p <= zero}.
- * @since Android 1.0
*/
public ECFieldFp(BigInteger p) {
this.p = p;
@@ -56,7 +53,6 @@
* Returns the size of the finite field (in bits).
*
* @return the size of the finite field (in bits).
- * @since Android 1.0
*/
public int getFieldSize() {
return p.bitLength();
@@ -66,7 +62,6 @@
* Returns the prime value {@code p} for this finite field.
*
* @return the prime value {@code p} for this finite field.
- * @since Android 1.0
*/
public BigInteger getP() {
return p;
@@ -79,7 +74,6 @@
* the object to compare to this finite field.
* @return {@code true} if the specified object is equal to this finite field,
* otherwise {@code false}.
- * @since Android 1.0
*/
public boolean equals(Object obj) {
// object equals itself
@@ -96,7 +90,6 @@
* Returns the hashcode value for this finite field.
*
* @return the hashcode value for this finite field.
- * @since Android 1.0
*/
public int hashCode() {
return p.hashCode();
diff --git a/security/src/main/java/java/security/spec/ECGenParameterSpec.java b/security/src/main/java/java/security/spec/ECGenParameterSpec.java
index 210b315..de4cd04 100644
--- a/security/src/main/java/java/security/spec/ECGenParameterSpec.java
+++ b/security/src/main/java/java/security/spec/ECGenParameterSpec.java
@@ -21,8 +21,6 @@
/**
* The parameter specification used to generate elliptic curve domain parameters.
- *
- * @since Android 1.0
*/
public class ECGenParameterSpec implements AlgorithmParameterSpec {
// Standard (or predefined) name for EC domain
@@ -35,7 +33,6 @@
*
* @param name
* the name of the elliptic curve domain parameter.
- * @since Android 1.0
*/
public ECGenParameterSpec(String name) {
this.name = name;
@@ -49,7 +46,6 @@
* curve domain parameter.
*
* @return the name
- * @since Android 1.0
*/
public String getName() {
return name;
diff --git a/security/src/main/java/java/security/spec/ECParameterSpec.java b/security/src/main/java/java/security/spec/ECParameterSpec.java
index e10757b..a1985db 100644
--- a/security/src/main/java/java/security/spec/ECParameterSpec.java
+++ b/security/src/main/java/java/security/spec/ECParameterSpec.java
@@ -23,8 +23,6 @@
/**
* The parameter specification used with Elliptic Curve Cryptography (ECC).
- *
- * @since Android 1.0
*/
public class ECParameterSpec implements AlgorithmParameterSpec {
// Elliptic curve for which this is parameter
@@ -51,7 +49,6 @@
* the co-factor.
* @throws IllegalArgumentException
* if {@code order <= zero} or {@code cofactor <= zero}.
- * @since Android 1.0
*/
public ECParameterSpec(EllipticCurve curve, ECPoint generator,
BigInteger order, int cofactor) {
@@ -84,7 +81,6 @@
* Returns the {@code cofactor}.
*
* @return the {@code cofactor}.
- * @since Android 1.0
*/
public int getCofactor() {
return cofactor;
@@ -94,7 +90,6 @@
* Returns the elliptic curve.
*
* @return the elliptic curve.
- * @since Android 1.0
*/
public EllipticCurve getCurve() {
return curve;
@@ -104,7 +99,6 @@
* Returns the generator (or base point).
*
* @return the generator (or base point).
- * @since Android 1.0
*/
public ECPoint getGenerator() {
return generator;
@@ -114,7 +108,6 @@
* Returns the order of the generator.
*
* @return the order of the generator.
- * @since Android 1.0
*/
public BigInteger getOrder() {
return order;
diff --git a/security/src/main/java/java/security/spec/ECPoint.java b/security/src/main/java/java/security/spec/ECPoint.java
index 3aba6c7..0751757 100644
--- a/security/src/main/java/java/security/spec/ECPoint.java
+++ b/security/src/main/java/java/security/spec/ECPoint.java
@@ -23,15 +23,11 @@
/**
* A Point on an Elliptic Curve in barycentric (or affine) coordinates.
- *
- * @since Android 1.0
*/
public class ECPoint {
/**
* The point on an Elliptic Curve at infinity.
- *
- * @since Android 1.0
*/
public static final ECPoint POINT_INFINITY = new ECPoint();
// affine X coordinate of this point
@@ -52,7 +48,6 @@
* the x-coordinate.
* @param affineY
* the y-coordinate.
- * @since Android 1.0
*/
public ECPoint(BigInteger affineX, BigInteger affineY) {
this.affineX = affineX;
@@ -69,7 +64,6 @@
* Returns the x-coordinate.
*
* @return the x-coordinate, or {@code null} for the infinite point.
- * @since Android 1.0
*/
public BigInteger getAffineX() {
return affineX;
@@ -79,7 +73,6 @@
* Returns the y-coordinate.
*
* @return the y-coordinate, or {@code null} fot the infinite point.
- * @since Android 1.0
*/
public BigInteger getAffineY() {
return affineY;
@@ -93,7 +86,6 @@
* the object to compare.
* @return {@code true} if the specified object and this elliptic curve
* point are equal, otherwise {@code false}.
- * @since Android 1.0
*/
public boolean equals(Object other) {
if (this == other) {
@@ -116,7 +108,6 @@
* Returns the hashcode of this elliptic curve point.
*
* @return the hashcode of this elliptic curve point.
- * @since Android 1.0
*/
public int hashCode() {
if (this.affineX != null) {
diff --git a/security/src/main/java/java/security/spec/ECPrivateKeySpec.java b/security/src/main/java/java/security/spec/ECPrivateKeySpec.java
index de778fd..1ddfec3 100644
--- a/security/src/main/java/java/security/spec/ECPrivateKeySpec.java
+++ b/security/src/main/java/java/security/spec/ECPrivateKeySpec.java
@@ -23,8 +23,6 @@
/**
* The parameters specifying an Elliptic Curve (EC) private key.
- *
- * @since Android 1.0
*/
public class ECPrivateKeySpec implements KeySpec {
// Private value associated with this key
@@ -40,7 +38,6 @@
* the private value {@code S}.
* @param params
* the domain parameter specification.
- * @since Android 1.0
*/
public ECPrivateKeySpec(BigInteger s, ECParameterSpec params) {
this.s = s;
@@ -58,7 +55,6 @@
* Returns the domain parameter specification.
*
* @return the domain parameter specification.
- * @since Android 1.0
*/
public ECParameterSpec getParams() {
return params;
@@ -68,7 +64,6 @@
* Returns the private value {@code S}.
*
* @return the private value {@code S}.
- * @since Android 1.0
*/
public BigInteger getS() {
return s;
diff --git a/security/src/main/java/java/security/spec/ECPublicKeySpec.java b/security/src/main/java/java/security/spec/ECPublicKeySpec.java
index da182b5..0c88590 100644
--- a/security/src/main/java/java/security/spec/ECPublicKeySpec.java
+++ b/security/src/main/java/java/security/spec/ECPublicKeySpec.java
@@ -21,8 +21,6 @@
/**
* The parameters specifying an Elliptic Curve (EC) public key.
- *
- * @since Android 1.0
*/
public class ECPublicKeySpec implements KeySpec {
// The public point
@@ -40,7 +38,6 @@
* the domain parameter specification.
* @throws IllegalArgumentException
* if the specified point {@code W} is at infinity.
- * @since Android 1.0
*/
public ECPublicKeySpec(ECPoint w, ECParameterSpec params) {
this.w = w;
@@ -63,7 +60,6 @@
* Returns the domain parameter specification.
*
* @return the domain parameter specification.
- * @since Android 1.0
*/
public ECParameterSpec getParams() {
return params;
@@ -73,7 +69,6 @@
* Returns the public elliptic curve point {@code W}.
*
* @return the public elliptic curve point {@code W}.
- * @since Android 1.0
*/
public ECPoint getW() {
return w;
diff --git a/security/src/main/java/java/security/spec/EllipticCurve.java b/security/src/main/java/java/security/spec/EllipticCurve.java
index 3ab2921..45ff042 100644
--- a/security/src/main/java/java/security/spec/EllipticCurve.java
+++ b/security/src/main/java/java/security/spec/EllipticCurve.java
@@ -24,8 +24,6 @@
/**
* An Elliptic Curve with its necessary values.
- *
- * @since Android 1.0
*/
public class EllipticCurve {
@@ -59,7 +57,6 @@
* the seed used for the generation of the curve.
* @throws IllegalArgumentException
* if the specified coefficients are not in the specified field.
- * @since Android 1.0
*/
public EllipticCurve(ECField field, BigInteger a, BigInteger b, byte[] seed) {
this.field = field;
@@ -115,7 +112,6 @@
* the coefficient {@code b}.
* @throws IllegalArgumentException
* if the specified coefficients are not in the specified field.
- * @since Android 1.0
*/
public EllipticCurve(ECField field, BigInteger a, BigInteger b) {
this(field, a, b, null);
@@ -125,7 +121,6 @@
* Returns the coefficient {@code a} of this elliptic curve.
*
* @return the coefficient {@code a} of this elliptic curve.
- * @since Android 1.0
*/
public BigInteger getA() {
return a;
@@ -135,7 +130,6 @@
* Returns the coefficient {@code b} of this elliptic curve.
*
* @return the coefficient {@code b} of this elliptic curve.
- * @since Android 1.0
*/
public BigInteger getB() {
return b;
@@ -145,7 +139,6 @@
* Returns the finite field of this elliptic curve.
*
* @return the finite field of this elliptic curve.
- * @since Android 1.0
*/
public ECField getField() {
return field;
@@ -156,7 +149,6 @@
*
* @return a copy of the seed that was used to generate this elliptic curve,
* or {@code null} if none specified.
- * @since Android 1.0
*/
public byte[] getSeed() {
if (seed == null) {
@@ -176,7 +168,6 @@
* the object to compare.
* @return {@code true} if the specified object is equal to this elliptic
* curve, otherwise {@code false}.
- * @since Android 1.0
*/
public boolean equals(Object other) {
if (this == other) {
@@ -195,7 +186,6 @@
* Returns the hashcode of this elliptic curve.
*
* @return the hashcode of this elliptic curve.
- * @since Android 1.0
*/
public int hashCode() {
// hash init is delayed
diff --git a/security/src/main/java/java/security/spec/EncodedKeySpec.java b/security/src/main/java/java/security/spec/EncodedKeySpec.java
index f199bca..d34794c 100644
--- a/security/src/main/java/java/security/spec/EncodedKeySpec.java
+++ b/security/src/main/java/java/security/spec/EncodedKeySpec.java
@@ -20,8 +20,6 @@
/**
* The abstract key specification for a public or a private key in encoded
* format.
- *
- * @since Android 1.0
*/
public abstract class EncodedKeySpec implements KeySpec {
// Encoded key
@@ -32,7 +30,6 @@
*
* @param encodedKey
* the encoded key bytes.
- * @since Android 1.0
*/
public EncodedKeySpec(byte[] encodedKey) {
// Defensively copies parameter
@@ -46,7 +43,6 @@
* Returns the encoded key bytes.
*
* @return the encoded key bytes.
- * @since Android 1.0
*/
public byte[] getEncoded() {
// Defensively copies private array
@@ -62,7 +58,6 @@
*
* @return the name of the encoding format of this encoded key
* specification.
- * @since Android 1.0
*/
public abstract String getFormat();
}
diff --git a/security/src/main/java/java/security/spec/InvalidKeySpecException.java b/security/src/main/java/java/security/spec/InvalidKeySpecException.java
index a83e984..4ae5877 100644
--- a/security/src/main/java/java/security/spec/InvalidKeySpecException.java
+++ b/security/src/main/java/java/security/spec/InvalidKeySpecException.java
@@ -22,15 +22,11 @@
/**
* The exception that is thrown when an invalid key specification is
* encountered.
- *
- * @since Android 1.0
*/
public class InvalidKeySpecException extends GeneralSecurityException {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
private static final long serialVersionUID = 3546139293998810778L;
@@ -39,7 +35,6 @@
*
* @param msg
* the detail message of this exception.
- * @since Android 1.0
*/
public InvalidKeySpecException(String msg) {
super(msg);
@@ -47,8 +42,6 @@
/**
* Creates a new {@code InvalidKeySpecException}.
- *
- * @since Android 1.0
*/
public InvalidKeySpecException() {
}
@@ -61,7 +54,6 @@
* the detail message of this exception.
* @param cause
* the cause of this exception.
- * @since Android 1.0
*/
public InvalidKeySpecException(String message, Throwable cause) {
super(message, cause);
@@ -72,7 +64,6 @@
*
* @param cause
* the cause of this exception.
- * @since Android 1.0
*/
public InvalidKeySpecException(Throwable cause) {
super(cause);
diff --git a/security/src/main/java/java/security/spec/InvalidParameterSpecException.java b/security/src/main/java/java/security/spec/InvalidParameterSpecException.java
index 668fda5..e308dd8 100644
--- a/security/src/main/java/java/security/spec/InvalidParameterSpecException.java
+++ b/security/src/main/java/java/security/spec/InvalidParameterSpecException.java
@@ -22,15 +22,11 @@
/**
* The exception that is thrown when an invalid parameter specification is
* encountered.
- *
- * @since Android 1.0
*/
public class InvalidParameterSpecException extends GeneralSecurityException {
/**
* The serial version identifier.
- *
- * @since Android 1.0
*/
private static final long serialVersionUID = -970468769593399342L;
@@ -40,7 +36,6 @@
*
* @param msg
* the detail message for this exception.
- * @since Android 1.0
*/
public InvalidParameterSpecException(String msg) {
super(msg);
@@ -48,9 +43,7 @@
/**
* Creates a new {@code InvalidParameterSpecException}.
- *
- * @since Android 1.0
*/
public InvalidParameterSpecException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/spec/KeySpec.java b/security/src/main/java/java/security/spec/KeySpec.java
index 350a7eb..fe8df1d 100644
--- a/security/src/main/java/java/security/spec/KeySpec.java
+++ b/security/src/main/java/java/security/spec/KeySpec.java
@@ -20,8 +20,6 @@
/**
* The marker interface for key specifications. The purpose is
* to group key specifications for cryptographic keys.
- *
- * @since Android 1.0
*/
public interface KeySpec {
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/java/security/spec/MGF1ParameterSpec.java b/security/src/main/java/java/security/spec/MGF1ParameterSpec.java
index a40f0b3..6475d90 100644
--- a/security/src/main/java/java/security/spec/MGF1ParameterSpec.java
+++ b/security/src/main/java/java/security/spec/MGF1ParameterSpec.java
@@ -26,17 +26,12 @@
* Defined in the <a
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-1.html">PKCS #1 v2.1</a>
* standard
- * </p>
- *
- * @since Android 1.0
*/
public class MGF1ParameterSpec implements AlgorithmParameterSpec {
/**
* The predefined MGF1 parameter specification with an "SHA-1" message
* digest.
- *
- * @since Android 1.0
*/
public static final MGF1ParameterSpec SHA1 =
new MGF1ParameterSpec("SHA-1"); //$NON-NLS-1$
@@ -44,8 +39,6 @@
/**
* The predefined MGF1 parameter specification with an "SHA-256" message
* digest.
- *
- * @since Android 1.0
*/
public static final MGF1ParameterSpec SHA256 =
new MGF1ParameterSpec("SHA-256"); //$NON-NLS-1$
@@ -53,8 +46,6 @@
/**
* The predefined MGF1 parameter specification with an "SHA-384" message
* digest.
- *
- * @since Android 1.0
*/
public static final MGF1ParameterSpec SHA384 =
new MGF1ParameterSpec("SHA-384"); //$NON-NLS-1$
@@ -62,8 +53,6 @@
/**
* The predefined MGF1 parameter specification with an "SHA-512" message
* digest.
- *
- * @since Android 1.0
*/
public static final MGF1ParameterSpec SHA512 =
new MGF1ParameterSpec("SHA-512"); //$NON-NLS-1$
@@ -77,7 +66,6 @@
*
* @param mdName
* the name of the message digest algorithm.
- * @since Android 1.0
*/
public MGF1ParameterSpec(String mdName) {
this.mdName = mdName;
@@ -90,7 +78,6 @@
* Returns the name of the message digest algorithm.
*
* @return the name of the message digest algorithm.
- * @since Android 1.0
*/
public String getDigestAlgorithm() {
return mdName;
diff --git a/security/src/main/java/java/security/spec/PKCS8EncodedKeySpec.java b/security/src/main/java/java/security/spec/PKCS8EncodedKeySpec.java
index 5cb67b8..6910789 100644
--- a/security/src/main/java/java/security/spec/PKCS8EncodedKeySpec.java
+++ b/security/src/main/java/java/security/spec/PKCS8EncodedKeySpec.java
@@ -20,8 +20,6 @@
/**
* The key specification for an encoded private key in ASN.1 format as defined
* in the PKCS#8 standard.
- *
- * @since Android 1.0
*/
public class PKCS8EncodedKeySpec extends EncodedKeySpec {
@@ -31,7 +29,6 @@
*
* @param encodedKey
* the encoded key bytes.
- * @since Android 1.0
*/
public PKCS8EncodedKeySpec(byte[] encodedKey) {
// Super class' ctor makes defensive parameter copy
@@ -42,7 +39,6 @@
* Returns a copy of the encoded key bytes.
*
* @return a copy of the encoded key bytes.
- * @since Android 1.0
*/
public byte[] getEncoded() {
// Super class' getEncoded() always returns a new array
@@ -54,7 +50,6 @@
* specification.
*
* @return the string "PKCS#8".
- * @since Android 1.0
*/
public final String getFormat() {
return "PKCS#8"; //$NON-NLS-1$
diff --git a/security/src/main/java/java/security/spec/PSSParameterSpec.java b/security/src/main/java/java/security/spec/PSSParameterSpec.java
index c6a5bc5..06c1d05 100644
--- a/security/src/main/java/java/security/spec/PSSParameterSpec.java
+++ b/security/src/main/java/java/security/spec/PSSParameterSpec.java
@@ -25,9 +25,6 @@
* Defined in the <a
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-1.html">PKCS #1 v2.1</a>
* standard.
- * </p>
- *
- * @since Android 1.0
*/
public class PSSParameterSpec implements AlgorithmParameterSpec {
@@ -40,8 +37,6 @@
* <li>salt length: {@code 20}</li>
* <li>trailer field: {@code -1}</li>
* </ul>
- *
- * @since Android 1.0
*/
public static final PSSParameterSpec DEFAULT = new PSSParameterSpec(20);
@@ -64,7 +59,6 @@
* the salt length (in bits).
* @throws IllegalArgumentException
* if {@code saltLen} is negative.
- * @since Android 1.0
*/
public PSSParameterSpec(int saltLen) {
if (saltLen < 0) {
@@ -94,7 +88,6 @@
* the trailer field value.
* @throws IllegalArgumentException
* if {@code saltLen} or {@code trailerField} is negative.
- * @since Android 1.0
*/
public PSSParameterSpec(String mdName, String mgfName,
AlgorithmParameterSpec mgfSpec, int saltLen, int trailerField) {
@@ -122,7 +115,6 @@
* Returns the length of the salt (in bits).
*
* @return the length of the salt (in bits).
- * @since Android 1.0
*/
public int getSaltLength() {
return saltLen;
@@ -132,7 +124,6 @@
* Returns the name of the message digest algorithm.
*
* @return the name of the message digest algorithm.
- * @since Android 1.0
*/
public String getDigestAlgorithm() {
return mdName;
@@ -142,7 +133,6 @@
* Returns the name of the mask generation function algorithm.
*
* @return the name of the mask generation function algorithm.
- * @since Android 1.0
*/
public String getMGFAlgorithm() {
return mgfName;
@@ -153,7 +143,6 @@
*
* @return the parameter for the mask generation function algorithm, or
* {@code null} if none specified.
- * @since Android 1.0
*/
public AlgorithmParameterSpec getMGFParameters() {
return mgfSpec;
@@ -163,7 +152,6 @@
* Returns the trailer field value.
*
* @return the trailer field value.
- * @since Android 1.0
*/
public int getTrailerField() {
return trailerField;
diff --git a/security/src/main/java/java/security/spec/RSAKeyGenParameterSpec.java b/security/src/main/java/java/security/spec/RSAKeyGenParameterSpec.java
index 06f3498..2377c75 100644
--- a/security/src/main/java/java/security/spec/RSAKeyGenParameterSpec.java
+++ b/security/src/main/java/java/security/spec/RSAKeyGenParameterSpec.java
@@ -21,22 +21,16 @@
/**
* The parameter specification for generating an RSA key pair.
- *
- * @since Android 1.0
*/
public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
/**
* The value of the public exponent {@code F0} = 3.
- *
- * @since Android 1.0
*/
public static final BigInteger F0 = BigInteger.valueOf(3L);
/**
* The value of the public exponent {@code F4} = 65537.
- *
- * @since Android 1.0
*/
public static final BigInteger F4 = BigInteger.valueOf(65537L);
@@ -53,7 +47,6 @@
* the size of the modulus (number of bits).
* @param publicExponent
* the value of the public exponent.
- * @since Android 1.0
*/
public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent) {
this.keysize = keysize;
@@ -64,7 +57,6 @@
* Returns the size of the modulus (number of bits).
*
* @return the size of the modulus (number of bits).
- * @since Android 1.0
*/
public int getKeysize() {
return keysize;
@@ -74,7 +66,6 @@
* Returns the value of the public exponent.
*
* @return the value of the public exponent.
- * @since Android 1.0
*/
public BigInteger getPublicExponent() {
return publicExponent;
diff --git a/security/src/main/java/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/security/src/main/java/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
index 93e3193..28469d7 100644
--- a/security/src/main/java/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
+++ b/security/src/main/java/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java
@@ -28,9 +28,6 @@
* Defined in the <a
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-1.html">PKCS #1 v2.1</a>
* standard.
- * </p>
- *
- * @since Android 1.0
*/
public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
// Public Exponent
@@ -74,7 +71,6 @@
* there are only the two primes ({@code p, q}).
* @throws IllegalArgumentException
* if {@code otherPrimeInfo} is not null but empty.
- * @since Android 1.0
*/
public RSAMultiPrimePrivateCrtKeySpec(
BigInteger modulus,
@@ -139,7 +135,6 @@
* Returns the CRT coefficient, {@code q^-1 mod p}.
*
* @return the CRT coefficient, {@code q^-1 mod p}.
- * @since Android 1.0
*/
public BigInteger getCrtCoefficient() {
return crtCoefficient;
@@ -150,7 +145,6 @@
*
* @return the information for the additional primes, or {@code null} if
* there are only the two primes ({@code p, q}).
- * @since Android 1.0
*/
public RSAOtherPrimeInfo[] getOtherPrimeInfo() {
// Clone array (if not null) to prevent subsequent modification
@@ -168,7 +162,6 @@
* Returns the exponent of the prime {@code p}.
*
* @return the exponent of the prime {@code p}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentP() {
return primeExponentP;
@@ -178,7 +171,6 @@
* Returns the exponent of the prime {@code q}.
*
* @return the exponent of the prime {@code q}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentQ() {
return primeExponentQ;
@@ -188,7 +180,6 @@
* Returns the prime factor {@code p}.
*
* @return the prime factor {@code p}.
- * @since Android 1.0
*/
public BigInteger getPrimeP() {
return primeP;
@@ -198,7 +189,6 @@
* Returns the prime factor {@code q}.
*
* @return the prime factor {@code q}.
- * @since Android 1.0
*/
public BigInteger getPrimeQ() {
return primeQ;
@@ -208,7 +198,6 @@
* Returns the public exponent {@code e}.
*
* @return the public exponent {@code e}.
- * @since Android 1.0
*/
public BigInteger getPublicExponent() {
return publicExponent;
diff --git a/security/src/main/java/java/security/spec/RSAOtherPrimeInfo.java b/security/src/main/java/java/security/spec/RSAOtherPrimeInfo.java
index 9b4828e..177ddf5 100644
--- a/security/src/main/java/java/security/spec/RSAOtherPrimeInfo.java
+++ b/security/src/main/java/java/security/spec/RSAOtherPrimeInfo.java
@@ -28,9 +28,6 @@
* Defined in the <a
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-1.html">PKCS #1 v2.1</a>
* standard.
- * </p>
- *
- * @since Android 1.0
*/
public class RSAOtherPrimeInfo {
// Prime
@@ -50,7 +47,6 @@
* the prime exponent.
* @param crtCoefficient
* the CRT coefficient.
- * @since Android 1.0
*/
public RSAOtherPrimeInfo(BigInteger prime,
BigInteger primeExponent, BigInteger crtCoefficient) {
@@ -72,7 +68,6 @@
* Returns the CRT coefficient.
*
* @return the CRT coefficient.
- * @since Android 1.0
*/
public final BigInteger getCrtCoefficient() {
return crtCoefficient;
@@ -82,7 +77,6 @@
* Returns the prime factor.
*
* @return the prime factor.
- * @since Android 1.0
*/
public final BigInteger getPrime() {
return prime;
@@ -92,7 +86,6 @@
* Returns the exponent.
*
* @return the exponent.
- * @since Android 1.0
*/
public final BigInteger getExponent() {
return primeExponent;
diff --git a/security/src/main/java/java/security/spec/RSAPrivateCrtKeySpec.java b/security/src/main/java/java/security/spec/RSAPrivateCrtKeySpec.java
index 1157099..e786e9e 100644
--- a/security/src/main/java/java/security/spec/RSAPrivateCrtKeySpec.java
+++ b/security/src/main/java/java/security/spec/RSAPrivateCrtKeySpec.java
@@ -26,9 +26,6 @@
* Defined in the <a
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-1.html">PKCS #1 v2.1</a>
* standard.
- * </p>
- *
- * @since Android 1.0
*/
public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec {
// Public Exponent
@@ -65,7 +62,6 @@
* the exponent of the prime {@code q}.
* @param crtCoefficient
* the CRT coefficient {@code q^-1 mod p}.
- * @since Android 1.0
*/
public RSAPrivateCrtKeySpec(BigInteger modulus,
BigInteger publicExponent,
@@ -90,7 +86,6 @@
* Returns the CRT coefficient, {@code q^-1 mod p}.
*
* @return the CRT coefficient, {@code q^-1 mod p}.
- * @since Android 1.0
*/
public BigInteger getCrtCoefficient() {
return crtCoefficient;
@@ -100,7 +95,6 @@
* Returns the exponent of the prime {@code p}.
*
* @return the exponent of the prime {@code p}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentP() {
return primeExponentP;
@@ -110,7 +104,6 @@
* Returns the exponent of the prime {@code q}.
*
* @return the exponent of the prime {@code q}.
- * @since Android 1.0
*/
public BigInteger getPrimeExponentQ() {
return primeExponentQ;
@@ -120,7 +113,6 @@
* Returns the prime factor {@code p}.
*
* @return the prime factor {@code p}.
- * @since Android 1.0
*/
public BigInteger getPrimeP() {
return primeP;
@@ -130,7 +122,6 @@
* Returns the prime factor {@code q}.
*
* @return the prime factor {@code q}.
- * @since Android 1.0
*/
public BigInteger getPrimeQ() {
return primeQ;
@@ -140,7 +131,6 @@
* Returns the public exponent {@code e}.
*
* @return the public exponent {@code e}.
- * @since Android 1.0
*/
public BigInteger getPublicExponent() {
return publicExponent;
diff --git a/security/src/main/java/java/security/spec/RSAPrivateKeySpec.java b/security/src/main/java/java/security/spec/RSAPrivateKeySpec.java
index bd7d4e8..c94420e 100644
--- a/security/src/main/java/java/security/spec/RSAPrivateKeySpec.java
+++ b/security/src/main/java/java/security/spec/RSAPrivateKeySpec.java
@@ -25,9 +25,6 @@
* Defined in the <a
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-1.html">PKCS #1 v2.1</a>
* standard
- * </p>
- *
- * @since Android 1.0
*/
public class RSAPrivateKeySpec implements KeySpec {
// Modulus
@@ -43,7 +40,6 @@
* the modulus {@code n}.
* @param privateExponent
* the private exponent {@code e}
- * @since Android 1.0
*/
public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent) {
this.modulus = modulus;
@@ -54,7 +50,6 @@
* Returns the modulus {@code n}.
*
* @return the modulus {@code n}.
- * @since Android 1.0
*/
public BigInteger getModulus() {
return modulus;
@@ -64,7 +59,6 @@
* Returns the private exponent {@code e}.
*
* @return the private exponent {@code e}.
- * @since Android 1.0
*/
public BigInteger getPrivateExponent() {
return privateExponent;
diff --git a/security/src/main/java/java/security/spec/RSAPublicKeySpec.java b/security/src/main/java/java/security/spec/RSAPublicKeySpec.java
index bd4c5b5..fe6de07 100644
--- a/security/src/main/java/java/security/spec/RSAPublicKeySpec.java
+++ b/security/src/main/java/java/security/spec/RSAPublicKeySpec.java
@@ -25,8 +25,6 @@
* Defined in the <a
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-1.html">PKCS #1 v2.1</a>
* standard.
- * </p>
- * @since Android 1.0
*/
public class RSAPublicKeySpec implements KeySpec {
// Modulus
@@ -42,7 +40,6 @@
* the modulus {@code n}.
* @param publicExponent
* the public exponent {@code d}.
- * @since Android 1.0
*/
public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) {
this.modulus = modulus;
@@ -53,7 +50,6 @@
* Returns the modulus {@code n}.
*
* @return the modulus {@code n}.
- * @since Android 1.0
*/
public BigInteger getModulus() {
return modulus;
@@ -63,7 +59,6 @@
* Returns the public exponent {@code d}.
*
* @return the public exponent {@code d}.
- * @since Android 1.0
*/
public BigInteger getPublicExponent() {
return publicExponent;
diff --git a/security/src/main/java/java/security/spec/X509EncodedKeySpec.java b/security/src/main/java/java/security/spec/X509EncodedKeySpec.java
index 6cc6104..61f3475 100644
--- a/security/src/main/java/java/security/spec/X509EncodedKeySpec.java
+++ b/security/src/main/java/java/security/spec/X509EncodedKeySpec.java
@@ -19,8 +19,6 @@
/**
* The key specification of an X.509 encoded key in ASN.1 format.
- *
- * @since Android 1.0
*/
public class X509EncodedKeySpec extends EncodedKeySpec {
@@ -30,7 +28,6 @@
*
* @param encodedKey
* the encoded key bytes.
- * @since Android 1.0
*/
public X509EncodedKeySpec(byte[] encodedKey) {
// Super class' ctor makes defensive parameter copy
@@ -41,7 +38,6 @@
* Returns the encoded key bytes.
*
* @return the encoded key bytes.
- * @since Android 1.0
*/
public byte[] getEncoded() {
// Super class' getEncoded() always returns a new array
@@ -53,7 +49,6 @@
* specification.
*
* @return the string "X.509".
- * @since Android 1.0
*/
public final String getFormat() {
return "X.509"; //$NON-NLS-1$
diff --git a/security/src/main/java/javax/security/cert/Certificate.java b/security/src/main/java/javax/security/cert/Certificate.java
index fb00789..ef513a3 100644
--- a/security/src/main/java/javax/security/cert/Certificate.java
+++ b/security/src/main/java/javax/security/cert/Certificate.java
@@ -29,34 +29,30 @@
/**
* Abstract class to represent identity certificates. It represents a way to
* verify the binding of a Principal and its public key. Examples are X.509,
- * PGP, and SDSI.
+ * PGP, and SDSI.
* <p>
* Note: This package is provided only for compatibility reasons.
* It contains a simplified version of the java.security.cert package that was
* previously used by JSSE (Java SSL package). All applications that do not have
* to be compatible with older versions of JSSE (that is before Java SDK 1.5)
* should only use java.security.cert.
- * </p>
- * @since Android 1.0
*/
public abstract class Certificate {
/**
* Creates a new {@code Certificate}.
- * @since Android 1.0
*/
public Certificate() {}
/**
* Compares the argument to this Certificate. If both have the same bytes
* they are assumed to be equal.
- *
+ *
* @param obj
* the {@code Certificate} to compare with this object
* @return <code>true</code> if {@code obj} is the same as this
* {@code Certificate}, <code>false</code> otherwise
* @see #hashCode
- * @since Android 1.0
*/
public boolean equals(Object obj) {
if (obj == this) {
@@ -77,10 +73,9 @@
* Returns an integer hash code for the receiver. Any two objects which
* return <code>true</code> when passed to <code>equals</code> must answer
* the same value for this method.
- *
+ *
* @return the receiver's hash
* @see #equals
- * @since Android 1.0
*/
public int hashCode() {
int res = 0;
@@ -96,18 +91,17 @@
/**
* Returns the encoded representation for this certificate.
- *
+ *
* @return the encoded representation for this certificate.
* @throws CertificateEncodingException
* if encoding fails.
- * @since Android 1.0
*/
public abstract byte[] getEncoded()
throws CertificateEncodingException;
/**
* Verifies that this certificate was signed with the given public key.
- *
+ *
* @param key
* public key for which verification should be performed.
* @throws CertificateException
@@ -120,7 +114,6 @@
* if there is no default provider
* @throws SignatureException
* if signature errors are detected
- * @since Android 1.0
*/
public abstract void verify(PublicKey key)
throws CertificateException, NoSuchAlgorithmException,
@@ -130,7 +123,7 @@
/**
* Verifies that this certificate was signed with the given public key. Uses
* the signature algorithm given by the provider.
- *
+ *
* @param key
* public key for which verification should be performed.
* @param sigProvider
@@ -145,7 +138,6 @@
* if the specified provider does not exists.
* @exception SignatureException
* if signature errors are detected
- * @since Android 1.0
*/
public abstract void verify(PublicKey key, String sigProvider)
throws CertificateException, NoSuchAlgorithmException,
@@ -155,17 +147,15 @@
/**
* Returns a string containing a concise, human-readable description of the
* receiver.
- *
+ *
* @return a printable representation for the receiver.
- * @since Android 1.0
*/
public abstract String toString();
/**
* Returns the public key corresponding to this certificate.
- *
+ *
* @return the public key corresponding to this certificate.
- * @since Android 1.0
*/
public abstract PublicKey getPublicKey();
}
diff --git a/security/src/main/java/javax/security/cert/CertificateEncodingException.java b/security/src/main/java/javax/security/cert/CertificateEncodingException.java
index 4091695..780e43f 100644
--- a/security/src/main/java/javax/security/cert/CertificateEncodingException.java
+++ b/security/src/main/java/javax/security/cert/CertificateEncodingException.java
@@ -27,20 +27,20 @@
* by JSSE (Java SSL package). All applications that do not have to be
* compatible with older versions of JSSE (that is before Java SDK 1.5) should
* only use java.security.cert.
- * </p>
- * @since Android 1.0
*/
public class CertificateEncodingException extends CertificateException {
+ /**
+ * @serial
+ */
private static final long serialVersionUID = -8187642723048403470L;
/**
* Creates a new {@code CertificateEncodingException} with the specified
* message.
- *
+ *
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertificateEncodingException(String msg) {
super(msg);
@@ -48,9 +48,7 @@
/**
* Creates a new {@code CertificateEncodingException}.
- *
- * @since Android 1.0
*/
public CertificateEncodingException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/javax/security/cert/CertificateException.java b/security/src/main/java/javax/security/cert/CertificateException.java
index f186e51..fd2a614 100644
--- a/security/src/main/java/javax/security/cert/CertificateException.java
+++ b/security/src/main/java/javax/security/cert/CertificateException.java
@@ -26,19 +26,19 @@
* by JSSE (Java SSL package). All applications that do not have to be
* compatible with older versions of JSSE (that is before Java SDK 1.5) should
* only use java.security.cert.
- * </p>
- * @since Android 1.0
*/
public class CertificateException extends Exception {
+ /**
+ * @serial
+ */
private static final long serialVersionUID = -5757213374030785290L;
/**
* Creates a new {@code CertificateException} with the specified message.
- *
+ *
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertificateException(String msg) {
super(msg);
@@ -46,9 +46,7 @@
/**
* Creates a new {@code CertificateException}.
- *
- * @since Android 1.0
*/
public CertificateException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/javax/security/cert/CertificateExpiredException.java b/security/src/main/java/javax/security/cert/CertificateExpiredException.java
index 62870a6..94e6558 100644
--- a/security/src/main/java/javax/security/cert/CertificateExpiredException.java
+++ b/security/src/main/java/javax/security/cert/CertificateExpiredException.java
@@ -25,20 +25,20 @@
* by JSSE (Java SSL package). All applications that do not have to be
* compatible with older versions of JSSE (that is before Java SDK 1.5) should
* only use java.security.cert.
- * </p>
- * @since Android 1.0
*/
public class CertificateExpiredException extends CertificateException {
+ /**
+ * @serial
+ */
private static final long serialVersionUID = 5091601212177261883L;
/**
* Creates a new {@code CertificateExpiredException} with the specified
* message.
- *
+ *
* @param msg
* the detail message for this exception
- * @since Android 1.0
*/
public CertificateExpiredException(String msg) {
super(msg);
@@ -46,9 +46,7 @@
/**
* Creates a new {@code CertificateExpiredException}.
- *
- * @since Android 1.0
*/
public CertificateExpiredException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/javax/security/cert/CertificateNotYetValidException.java b/security/src/main/java/javax/security/cert/CertificateNotYetValidException.java
index 6f32945..8fe0a33 100644
--- a/security/src/main/java/javax/security/cert/CertificateNotYetValidException.java
+++ b/security/src/main/java/javax/security/cert/CertificateNotYetValidException.java
@@ -25,20 +25,20 @@
* by JSSE (Java SSL package). All applications that do not have to be
* compatible with older versions of JSSE (that is before Java SDK 1.5) should
* only use java.security.cert.
- * </p>
- * @since Android 1.0
*/
public class CertificateNotYetValidException extends CertificateException {
+ /**
+ * @serial
+ */
private static final long serialVersionUID = -8976172474266822818L;
/**
* Creates a new {@code CertificateNotYetValidException} with the specified
* message.
- *
+ *
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertificateNotYetValidException(String msg) {
super(msg);
@@ -46,9 +46,7 @@
/**
* Creates a new {@code CertificateNotYetValidException}.
- *
- * @since Android 1.0
*/
public CertificateNotYetValidException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/javax/security/cert/CertificateParsingException.java b/security/src/main/java/javax/security/cert/CertificateParsingException.java
index 9b208e6..48986c0 100644
--- a/security/src/main/java/javax/security/cert/CertificateParsingException.java
+++ b/security/src/main/java/javax/security/cert/CertificateParsingException.java
@@ -25,20 +25,20 @@
* by JSSE (Java SSL package). All applications that do not have to be
* compatible with older versions of JSSE (that is before Java SDK 1.5) should
* only use java.security.cert.
- * </p>
- * @since Android 1.0
*/
public class CertificateParsingException extends CertificateException {
+ /**
+ * @serial
+ */
private static final long serialVersionUID = -8449352422951136229L;
/**
* Creates a new {@code CertificateParsingException} with the specified
* message.
- *
+ *
* @param msg
* the detail message for the exception.
- * @since Android 1.0
*/
public CertificateParsingException(String msg) {
super(msg);
@@ -46,9 +46,7 @@
/**
* Creates a new {@code CertificateParsingException}.
- *
- * @since Android 1.0
*/
public CertificateParsingException() {
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/javax/security/cert/X509Certificate.java b/security/src/main/java/javax/security/cert/X509Certificate.java
index 77bffae..8877386 100644
--- a/security/src/main/java/javax/security/cert/X509Certificate.java
+++ b/security/src/main/java/javax/security/cert/X509Certificate.java
@@ -44,15 +44,12 @@
* <p>
* This represents a standard way for accessing the attributes of X.509 v1
* certificates.
- * </p>
* <p>
* Note: This package is provided only for compatibility reasons.
* It contains a simplified version of the java.security.cert package that was
* previously used by JSSE (Java SSL package). All applications that do not have
* to be compatible with older versions of JSSE (that is before Java SDK 1.5)
* should only use java.security.cert.
- * </p>
- * @since Android 1.0
*/
public abstract class X509Certificate extends Certificate {
@@ -76,8 +73,6 @@
/**
* Creates a new {@code X509Certificate}.
- *
- * @since Android 1.0
*/
public X509Certificate() {
super();
@@ -86,13 +81,12 @@
/**
* Creates a new {@code X509Certificate} and initializes it from the
* specified input stream.
- *
+ *
* @param inStream
* input stream containing data to initialize the certificate.
* @return the certificate initialized from the specified input stream
* @throws CertificateException
* if the certificate cannot be created or initialized.
- * @since Android 1.0
*/
public static final X509Certificate getInstance(InputStream inStream)
throws CertificateException {
@@ -220,13 +214,12 @@
/**
* Creates a new {@code X509Certificate} and initializes it from the
* specified byte array.
- *
+ *
* @param certData
* byte array containing data to initialize the certificate.
* @return the certificate initialized from the specified byte array
* @throws CertificateException
* if the certificate cannot be created or initialized.
- * @since Android 1.0
*/
public static final X509Certificate getInstance(byte[] certData)
throws CertificateException {
@@ -241,26 +234,23 @@
* Checks whether the certificate is currently valid.
* <p>
* The validity defined in ASN.1:
- *
+ *
* <pre>
* validity Validity
- *
- * Validity ::= SEQUENCE {
- * notBefore CertificateValidityDate,
+ *
+ * Validity ::= SEQUENCE {
+ * notBefore CertificateValidityDate,
* notAfter CertificateValidityDate }
- *
- * CertificateValidityDate ::= CHOICE {
- * utcTime UTCTime,
+ *
+ * CertificateValidityDate ::= CHOICE {
+ * utcTime UTCTime,
* generalTime GeneralizedTime }
* </pre>
- *
- * </p>
- *
+ *
* @throws CertificateExpiredException
* if the certificate has expired.
* @throws CertificateNotYetValidException
* if the certificate is not yet valid.
- * @since Android 1.0
*/
public abstract void checkValidity()
throws CertificateExpiredException, CertificateNotYetValidException;
@@ -268,7 +258,7 @@
/**
* Checks whether the certificate is valid at the specified date.
- *
+ *
* @param date
* the date to check the validity against.
* @throws CertificateExpiredException
@@ -276,7 +266,6 @@
* @throws CertificateNotYetValidException
* if the certificate is not yet valid.
* @see #checkValidity()
- * @since Android 1.0
*/
public abstract void checkValidity(Date date)
throws CertificateExpiredException, CertificateNotYetValidException;
@@ -285,15 +274,12 @@
* Returns the certificates {@code version} (version number).
* <p>
* The version defined is ASN.1:
- *
+ *
* <pre>
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
* </pre>
- *
- * </p>
- *
+ *
* @return the version number.
- * @since Android 1.0
*/
public abstract int getVersion();
@@ -301,15 +287,12 @@
* Returns the {@code serialNumber} of the certificate.
* <p>
* The ASN.1 definition of {@code serialNumber}:
- *
+ *
* <pre>
* CertificateSerialNumber ::= INTEGER
* </pre>
- *
- * </p>
- *
+ *
* @return the serial number.
- * @since Android 1.0
*/
public abstract BigInteger getSerialNumber();
@@ -318,31 +301,28 @@
* implementation specific {@code Principal} object.
* <p>
* The ASN.1 definition of {@code issuer}:
- *
+ *
* <pre>
* issuer Name
- *
+ *
* Name ::= CHOICE {
* RDNSequence }
- *
+ *
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
- *
+ *
* RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
- *
+ *
* AttributeTypeAndValue ::= SEQUENCE {
* type AttributeType,
* value AttributeValue }
- *
+ *
* AttributeType ::= OBJECT IDENTIFIER
- *
+ *
* AttributeValue ::= ANY DEFINED BY AttributeType
* </pre>
- *
- * </p>
- *
+ *
* @return the {@code issuer} as an implementation specific {@code
* Principal}.
- * @since Android 1.0
*/
public abstract Principal getIssuerDN();
@@ -351,73 +331,65 @@
* implementation specific {@code Principal} object.
* <p>
* The ASN.1 definition of {@code subject}:
- *
+ *
* <pre>
* subject Name
- *
+ *
* Name ::= CHOICE {
* RDNSequence }
- *
+ *
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
- *
+ *
* RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
- *
+ *
* AttributeTypeAndValue ::= SEQUENCE {
* type AttributeType,
* value AttributeValue }
- *
+ *
* AttributeType ::= OBJECT IDENTIFIER
- *
+ *
* AttributeValue ::= ANY DEFINED BY AttributeType
* </pre>
- *
- * </p>
- *
+ *
* @return the {@code subject} (subject distinguished name).
- * @since Android 1.0
*/
public abstract Principal getSubjectDN();
/**
* Returns the {@code notBefore} date from the validity period of the
* certificate.
- *
+ *
* @return the start of the validity period.
- * @since Android 1.0
*/
public abstract Date getNotBefore();
/**
* Returns the {@code notAfter} date of the validity period of the
* certificate.
- *
+ *
* @return the end of the validity period.
- * @since Android 1.0
*/
public abstract Date getNotAfter();
/**
* Returns the name of the algorithm for the certificate signature.
- *
+ *
* @return the signature algorithm name.
- * @since Android 1.0
*/
public abstract String getSigAlgName();
/**
* Returns the OID of the signature algorithm from the certificate.
- *
+ *
* @return the OID of the signature algorithm.
- * @since Android 1.0
*/
public abstract String getSigAlgOID();
/**
* Returns the parameters of the signature algorithm in DER-encoded format.
- *
+ *
* @return the parameters of the signature algorithm, or null if none are
* used.
- * @since Android 1.0
*/
public abstract byte[] getSigAlgParams();
}
diff --git a/security/src/main/java/org/apache/harmony/security/DefaultPolicyScanner.java b/security/src/main/java/org/apache/harmony/security/DefaultPolicyScanner.java
index ba3229b..afab96e 100644
--- a/security/src/main/java/org/apache/harmony/security/DefaultPolicyScanner.java
+++ b/security/src/main/java/org/apache/harmony/security/DefaultPolicyScanner.java
@@ -127,9 +127,9 @@
break parsing;
case StreamTokenizer.TT_WORD:
- if ("keystore".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
+ if (Util.equalsIgnoreCase("keystore", st.sval)) { //$NON-NLS-1$
keystoreEntries.add(readKeystoreEntry(st));
- } else if ("grant".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
+ } else if (Util.equalsIgnoreCase("grant", st.sval)) { //$NON-NLS-1$
grantEntries.add(readGrantEntry(st));
} else {
handleUnexpectedToken(st, Messages.getString("security.89")); //$NON-NLS-1$
@@ -208,19 +208,19 @@
switch (st.nextToken()) {
case StreamTokenizer.TT_WORD:
- if ("signedby".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
+ if (Util.equalsIgnoreCase("signedby", st.sval)) { //$NON-NLS-1$
if (st.nextToken() == '"') {
ge.signers = st.sval;
} else {
handleUnexpectedToken(st, Messages.getString("security.8B")); //$NON-NLS-1$
}
- } else if ("codebase".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
+ } else if (Util.equalsIgnoreCase("codebase", st.sval)) { //$NON-NLS-1$
if (st.nextToken() == '"') {
ge.codebase = st.sval;
} else {
handleUnexpectedToken(st, Messages.getString("security.8C")); //$NON-NLS-1$
}
- } else if ("principal".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
+ } else if (Util.equalsIgnoreCase("principal", st.sval)) { //$NON-NLS-1$
ge.addPrincipal(readPrincipalEntry(st));
} else {
handleUnexpectedToken(st);
@@ -308,7 +308,7 @@
switch (st.nextToken()) {
case StreamTokenizer.TT_WORD:
- if ("permission".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
+ if (Util.equalsIgnoreCase("permission", st.sval)) { //$NON-NLS-1$
PermissionEntry pe = new PermissionEntry();
if (st.nextToken() == StreamTokenizer.TT_WORD) {
pe.klass = st.sval;
@@ -326,7 +326,7 @@
}
}
if (st.ttype == StreamTokenizer.TT_WORD
- && "signedby".equalsIgnoreCase(st.sval)) { //$NON-NLS-1$
+ && Util.equalsIgnoreCase("signedby", st.sval)) { //$NON-NLS-1$
if (st.nextToken() == '"') {
pe.signers = st.sval;
} else {
diff --git a/security/src/main/java/org/apache/harmony/security/PolicyEntry.java b/security/src/main/java/org/apache/harmony/security/PolicyEntry.java
index 4c7aa5b..0037ad6 100644
--- a/security/src/main/java/org/apache/harmony/security/PolicyEntry.java
+++ b/security/src/main/java/org/apache/harmony/security/PolicyEntry.java
@@ -22,6 +22,8 @@
package org.apache.harmony.security;
+import java.net.URL;
+import java.security.CodeSigner;
import java.security.CodeSource;
import java.security.Permission;
import java.security.Principal;
@@ -30,7 +32,6 @@
import org.apache.harmony.security.fortress.PolicyUtils;
-
/**
* This class represents an elementary block of a security policy. It associates
* a CodeSource of an executable code, Principals allowed to execute the code,
@@ -55,7 +56,7 @@
*/
public PolicyEntry(CodeSource cs, Collection<? extends Principal> prs,
Collection<? extends Permission> permissions) {
- this.cs = cs;
+ this.cs = (cs != null) ? normalizeCodeSource(cs) : null;
this.principals = (prs == null || prs.isEmpty()) ? null
: (Principal[]) prs.toArray(new Principal[prs.size()]);
this.permissions = (permissions == null || permissions.isEmpty()) ? null
@@ -68,7 +69,31 @@
* imply() method.
*/
public boolean impliesCodeSource(CodeSource codeSource) {
- return (cs == null) ? true : cs.implies(codeSource);
+ if (cs == null) {
+ return true;
+ }
+
+ if (codeSource == null) {
+ return false;
+ }
+ return cs.implies(normalizeCodeSource(codeSource));
+ }
+
+ private CodeSource normalizeCodeSource(CodeSource codeSource) {
+ URL codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation());
+ CodeSource result = codeSource;
+
+ if (codeSourceURL != codeSource.getLocation()) {
+ // URL was normalized - recreate codeSource with new URL
+ CodeSigner[] signers = codeSource.getCodeSigners();
+ if (signers == null) {
+ result = new CodeSource(codeSourceURL, codeSource
+ .getCertificates());
+ } else {
+ result = new CodeSource(codeSourceURL, signers);
+ }
+ }
+ return result;
}
/**
diff --git a/security/src/main/java/org/apache/harmony/security/Util.java b/security/src/main/java/org/apache/harmony/security/Util.java
new file mode 100644
index 0000000..e6e764f
--- /dev/null
+++ b/security/src/main/java/org/apache/harmony/security/Util.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.security;
+
+public class Util {
+
+ public static String toUpperCase(String s) {
+ return org.apache.harmony.luni.util.Util.toASCIIUpperCase(s);
+ }
+
+ public static boolean equalsIgnoreCase(String s1, String s2) {
+ s1 = org.apache.harmony.luni.util.Util.toASCIIUpperCase(s1);
+ s2 = org.apache.harmony.luni.util.Util.toASCIIUpperCase(s2);
+ return s1.equals(s2);
+ }
+}
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/ASN1Choice.java b/security/src/main/java/org/apache/harmony/security/asn1/ASN1Choice.java
index 1f5534d..e8db789 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/ASN1Choice.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/ASN1Choice.java
@@ -25,6 +25,7 @@
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Iterator;
+import java.util.Map;
import java.util.TreeMap;
import org.apache.harmony.security.internal.nls.Messages;
@@ -269,12 +270,14 @@
// fill identifiers array
int size = map.size();
identifiers = new int[2][size];
- Iterator it = map.keySet().iterator();
+ Iterator it = map.entrySet().iterator();
+
for (int i = 0; i < size; i++) {
- BigInteger identifier = (BigInteger) it.next();
+ Map.Entry entry = (Map.Entry) it.next();
+ BigInteger identifier = (BigInteger) entry.getKey();
identifiers[0][i] = identifier.intValue();
- identifiers[1][i] = ((BigInteger) map.get(identifier)).intValue();
+ identifiers[1][i] = ((BigInteger) entry.getValue()).intValue();
}
this.type = type;
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/ASN1GeneralizedTime.java b/security/src/main/java/org/apache/harmony/security/asn1/ASN1GeneralizedTime.java
index 4ec103b..4908afb 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/ASN1GeneralizedTime.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/ASN1GeneralizedTime.java
@@ -23,6 +23,7 @@
package org.apache.harmony.security.asn1;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
@@ -30,10 +31,7 @@
/**
* This class represents ASN.1 GeneralizedTime type.
*
- * According to X.680 specification this type is defined as follows:
- * GeneralizedTime ::= [UNIVERSAL 24] IMPLICIT VisibleString
- *
- * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a>
+ * @see http://asn1.elibel.tm.fr/en/standards/index.htm
*/
public class ASN1GeneralizedTime extends ASN1Time {
@@ -114,7 +112,13 @@
if (temp.charAt(currLength) == '.') {
temp = temp.substring(0, currLength);
}
- out.content = (temp + "Z").getBytes(); //$NON-NLS-1$
+
+ try {
+ out.content = (temp + "Z").getBytes("UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+
out.length = ((byte[]) out.content).length;
}
}
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/ASN1Oid.java b/security/src/main/java/org/apache/harmony/security/asn1/ASN1Oid.java
index 6292870..960dc0f 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/ASN1Oid.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/ASN1Oid.java
@@ -154,7 +154,7 @@
public Object getDecodedObject(BerInputStream in) throws IOException {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
int element;
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/ASN1StringType.java b/security/src/main/java/org/apache/harmony/security/asn1/ASN1StringType.java
index 55f48fa..0bc4b8a 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/ASN1StringType.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/ASN1StringType.java
@@ -118,7 +118,9 @@
* @return java.land.String object
*/
public Object getDecodedObject(BerInputStream in) throws IOException {
- return new String(in.buffer, in.contentOffset, in.length);
+ /* To ensure we get the correct encoding on non-ASCII platforms, specify
+ that we wish to convert from ASCII to the default platform encoding */
+ return new String(in.buffer, in.contentOffset, in.length, "ISO-8859-1");
}
//
@@ -137,11 +139,15 @@
}
public void setEncodingContent(BerOutputStream out) {
-
- byte[] bytes = ((String) out.content).getBytes();
-
- out.content = bytes;
- out.length = bytes.length;
+ try {
+ byte[] bytes = ((String) out.content).getBytes("UTF-8"); //$NON-NLS-1$
+ out.content = bytes;
+ out.length = bytes.length;
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.getMessage());
+ }
}
}
+
+
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/ASN1UTCTime.java b/security/src/main/java/org/apache/harmony/security/asn1/ASN1UTCTime.java
index 0dd7ae4..3d2cb3e 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/ASN1UTCTime.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/ASN1UTCTime.java
@@ -23,6 +23,7 @@
package org.apache.harmony.security.asn1;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
@@ -30,10 +31,7 @@
/**
* This class represents ASN.1 UTCTime type
*
- * According to X.680 specification this type is defined as follows:
- * UTCTime ::= [UNIVERSAL 23] IMPLICIT VisibleString
- *
- * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a>
+ * @see http://asn1.elibel.tm.fr/en/standards/index.htm
*/
public class ASN1UTCTime extends ASN1Time {
@@ -118,7 +116,11 @@
public void setEncodingContent(BerOutputStream out) {
SimpleDateFormat sdf = new SimpleDateFormat(UTC_PATTERN);
sdf.setTimeZone(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$
- out.content = sdf.format(out.content).getBytes();
+ try {
+ out.content = sdf.format(out.content).getBytes("UTF-8"); //$NON-NLS-1$
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.getMessage());
+ }
out.length = ((byte[]) out.content).length;
}
}
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/BerInputStream.java b/security/src/main/java/org/apache/harmony/security/asn1/BerInputStream.java
index 68819b8..531d760 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/BerInputStream.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/BerInputStream.java
@@ -25,7 +25,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Calendar;
import org.apache.harmony.security.internal.nls.Messages;
@@ -132,8 +131,8 @@
if (length != INDEFINIT_LENGTH) {
// input stream has definite length encoding
// check allocated length to avoid further reallocations
- if (buffer.length < length) {
- byte[] newBuffer = new byte[length];
+ if (buffer.length < (length + offset)) {
+ byte[] newBuffer = new byte[length + offset];
System.arraycopy(buffer, 0, newBuffer, 0, offset);
buffer = newBuffer;
}
@@ -916,9 +915,22 @@
if (in == null) {
offset += length;
} else {
- if (in.read(buffer, offset, length) != length) {
- throw new ASN1Exception(Messages.getString("security.13C")); //$NON-NLS-1$
+ int bytesRead = in.read(buffer, offset, length);
+
+ if (bytesRead != length) {
+ // if input stream didn't return all data at once
+ // try to read it in several blocks
+ int c = bytesRead;
+ do {
+ if (c < 1 || bytesRead > length) {
+ throw new ASN1Exception(Messages
+ .getString("security.13C")); //$NON-NLS-1$
+ }
+ c = in.read(buffer, offset + bytesRead, length - bytesRead);
+ bytesRead += c;
+ } while (bytesRead != length);
}
+
offset += length;
}
}
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/InformationObjectSet.java b/security/src/main/java/org/apache/harmony/security/asn1/InformationObjectSet.java
index 2a267e5..06ada53 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/InformationObjectSet.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/InformationObjectSet.java
@@ -95,7 +95,7 @@
return intHash & 0x7FFFFFFF; // only positive
}
- private class Entry {
+ private static class Entry {
public int[] oid;
public Object object;
diff --git a/security/src/main/java/org/apache/harmony/security/asn1/ObjectIdentifier.java b/security/src/main/java/org/apache/harmony/security/asn1/ObjectIdentifier.java
index 0e7269a..0d3a77a 100644
--- a/security/src/main/java/org/apache/harmony/security/asn1/ObjectIdentifier.java
+++ b/security/src/main/java/org/apache/harmony/security/asn1/ObjectIdentifier.java
@@ -243,7 +243,7 @@
* @return oid string representation
*/
public static String toString(int[] oid) {
- StringBuffer sb = new StringBuffer(3 * oid.length);
+ StringBuilder sb = new StringBuilder(3 * oid.length);
for (int i = 0; i < oid.length - 1; ++i) {
sb.append(oid[i]);
diff --git a/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicy.java b/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicy.java
index 2aa474e..df425a4 100644
--- a/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicy.java
+++ b/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicy.java
@@ -163,7 +163,7 @@
// A flag indicating brand new instance which needs to be loaded
// on the first appeal to it's data.
- private boolean initiailized;
+ private boolean initialized;
/**
* Default constructor, equivalent to
@@ -180,7 +180,7 @@
*/
public DefaultPolicy(DefaultPolicyParser dpr) {
parser = dpr;
- initiailized = false;
+ initialized = false;
refresh();
}
@@ -191,9 +191,9 @@
* to be <code>null</code> if the domain is <code>null</code>.
*/
public PermissionCollection getPermissions(ProtectionDomain pd) {
- if (!initiailized) {
+ if (!initialized) {
synchronized (this) {
- if (!initiailized) {
+ if (!initialized) {
refresh();
}
}
@@ -230,9 +230,9 @@
* The evaluation assumes that current principals are undefined.
*/
public PermissionCollection getPermissions(CodeSource cs) {
- if (!initiailized) {
+ if (!initialized) {
synchronized (this) {
- if (!initiailized) {
+ if (!initialized) {
refresh();
}
}
@@ -306,6 +306,6 @@
cache.clear();
}
- initiailized = true;
+ initialized = true;
}
}
diff --git a/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java b/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java
index fafa66c..c809fe4 100644
--- a/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java
+++ b/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java
@@ -25,7 +25,6 @@
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.File;
import java.io.Reader;
import java.net.URL;
import java.security.cert.Certificate;
@@ -62,8 +61,7 @@
* a pluggable scanner and converts received tokens to a set of
* {@link org.apache.harmony.security.PolicyEntry PolicyEntries}.
* For details of policy format, see the
- * {@link org.apache.harmony.security.fortress.DefaultPolicy default policy
- * description}.
+ * {@link org.apache.harmony.security.DefaultPolicy default policy description}.
* <br>
* For ordinary uses, this class has just one public method <code>parse()</code>,
* which performs the main task.
@@ -73,7 +71,7 @@
* This implementation is effectively thread-safe, as it has no field references
* to data being processed (that is, passes all the data as method parameters).
*
- * @see org.apache.harmony.security.fortress.DefaultPolicy
+ * @see org.apache.harmony.security.DefaultPolicy
* @see org.apache.harmony.security.DefaultPolicyScanner
* @see org.apache.harmony.security.PolicyEntry
*/
@@ -188,7 +186,7 @@
* of the GrantEntry
* @see DefaultPolicyScanner.PrincipalEntry
* @see DefaultPolicyScanner.PermissionEntry
- * @see org.apache.harmony.security.fortress.PolicyUtils
+ * @see org.apache.harmony.security.PolicyUtils
*/
protected PolicyEntry resolveGrant(DefaultPolicyScanner.GrantEntry ge,
KeyStore ks, Properties system, boolean resolve) throws Exception {
@@ -200,14 +198,6 @@
if (ge.codebase != null) {
codebase = new URL(resolve ? PolicyUtils.expandURL(ge.codebase,
system) : ge.codebase);
- //Fix HARMONY-1963
- if ("file".equals(codebase.getProtocol())) { //$NON-NLS-1$
- File codeFile = new File(codebase.getFile());
- if (codeFile.isAbsolute()) {
- codebase = new URL("file://" + //$NON-NLS-1$
- codeFile.getAbsolutePath());
- }
- }
}
if (ge.signers != null) {
if (resolve) {
@@ -342,7 +332,7 @@
if ("self".equals(protocol)) { //$NON-NLS-1$
//need expanding to list of principals in grant clause
if (ge.principals != null && ge.principals.size() != 0) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (Iterator<PrincipalEntry> iter = ge.principals.iterator(); iter
.hasNext();) {
DefaultPolicyScanner.PrincipalEntry pr = iter
@@ -385,7 +375,7 @@
private String pc2str(Principal pc) {
String klass = pc.getClass().getName();
String name = pc.getName();
- StringBuffer sb = new StringBuffer(klass.length() + name.length()
+ StringBuilder sb = new StringBuilder(klass.length() + name.length()
+ 5);
return sb.append(klass).append(" \"").append(name).append("\"") //$NON-NLS-1$ //$NON-NLS-2$
.toString();
diff --git a/security/src/main/java/org/apache/harmony/security/fortress/Engine.java b/security/src/main/java/org/apache/harmony/security/fortress/Engine.java
index 3b6f5d5..19fed41 100644
--- a/security/src/main/java/org/apache/harmony/security/fortress/Engine.java
+++ b/security/src/main/java/org/apache/harmony/security/fortress/Engine.java
@@ -25,6 +25,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+import org.apache.harmony.security.Util;
import org.apache.harmony.security.internal.nls.Messages;
@@ -89,7 +90,7 @@
}
Services.refresh();
if (returnedService != null
- && algorithm.equalsIgnoreCase(lastAlgorithm)
+ && Util.equalsIgnoreCase(algorithm, lastAlgorithm)
&& refreshNumber == Services.refreshNumber) {
serv = returnedService;
} else {
@@ -97,9 +98,9 @@
throw new NoSuchAlgorithmException(Messages.getString("security.14A", //$NON-NLS-1$
serviceName, algorithm));
}
- serv = Services.getService(new StringBuffer(128)
+ serv = Services.getService(new StringBuilder(128)
.append(serviceName).append(".").append( //$NON-NLS-1$
- algorithm.toUpperCase()).toString());
+ Util.toUpperCase(algorithm)).toString());
if (serv == null) {
throw new NoSuchAlgorithmException(Messages.getString("security.14A", //$NON-NLS-1$
serviceName, algorithm));
diff --git a/security/src/main/java/org/apache/harmony/security/fortress/PolicyUtils.java b/security/src/main/java/org/apache/harmony/security/fortress/PolicyUtils.java
index eda7327..b4e0e6a 100644
--- a/security/src/main/java/org/apache/harmony/security/fortress/PolicyUtils.java
+++ b/security/src/main/java/org/apache/harmony/security/fortress/PolicyUtils.java
@@ -25,6 +25,8 @@
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
import java.security.Permission;
@@ -39,6 +41,7 @@
import java.util.List;
import java.util.Properties;
+import org.apache.harmony.security.Util;
import org.apache.harmony.security.internal.nls.Messages;
/**
@@ -282,6 +285,56 @@
throws ExpansionFailedException {
return expand(str, properties).replace(File.separatorChar, '/');
}
+
+ /**
+ * Normalizes URLs to standard ones, eliminating pathname symbols.
+ *
+ * @param codebase -
+ * the original URL.
+ * @return - the normalized URL.
+ */
+ public static URL normalizeURL(URL codebase) {
+ if (codebase != null && "file".equals(codebase.getProtocol())) { //$NON-NLS-1$
+ try {
+ if (codebase.getHost().length() == 0) {
+ String path = codebase.getFile();
+
+ if (path.length() == 0) {
+ // codebase is "file:"
+ path = "*";
+ }
+ return filePathToURI(new File(path)
+ .getAbsolutePath()).normalize().toURL();
+ } else {
+ // codebase is "file://<smth>"
+ return codebase.toURI().normalize().toURL();
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ return codebase;
+ }
+
+ /**
+ * Converts a file path to URI without accessing file system
+ * (like {File#toURI()} does).
+ *
+ * @param path -
+ * file path.
+ * @return - the resulting URI.
+ * @throw URISyntaxException
+ */
+ public static URI filePathToURI(String path) throws URISyntaxException {
+ path = path.replace(File.separatorChar, '/');
+
+ if (!path.startsWith("/")) { //$NON-NLS-1$
+ return new URI("file", null, //$NON-NLS-1$
+ new StringBuilder(path.length() + 1).append('/')
+ .append(path).toString(), null, null);
+ }
+ return new URI("file", null, path, null, null); //$NON-NLS-1$
+ }
/**
* Instances of this interface are intended for resolving
@@ -371,7 +424,7 @@
* @see #expand(String, Properties)
*/
public static boolean canExpandProperties() {
- return !FALSE.equalsIgnoreCase(AccessController
+ return !Util.equalsIgnoreCase(FALSE,AccessController
.doPrivileged(new SecurityPropertyAccessor(POLICY_EXPAND)));
}
@@ -417,7 +470,7 @@
URL dynamicURL = null;
//first check if policy is set via system properties
- if (!FALSE.equalsIgnoreCase(AccessController
+ if (!Util.equalsIgnoreCase(FALSE, AccessController
.doPrivileged(security.key(POLICY_ALLOW_DYNAMIC)))) {
String location = system.getProperty(systemUrlKey);
if (location != null) {
diff --git a/security/src/main/java/org/apache/harmony/security/fortress/Services.java b/security/src/main/java/org/apache/harmony/security/fortress/Services.java
index 300854a..60d9edd 100644
--- a/security/src/main/java/org/apache/harmony/security/fortress/Services.java
+++ b/security/src/main/java/org/apache/harmony/security/fortress/Services.java
@@ -33,6 +33,8 @@
import java.util.Map;
import java.util.Set;
+import org.apache.harmony.security.Util;
+
/**
* This class contains information about all registered providers and preferred
@@ -56,7 +58,7 @@
/**
* Refresh number
*/
- public static int refreshNumber = 1;
+ static int refreshNumber = 1;
// Registered providers
private static final List<Provider> providers = new ArrayList<Provider>(20);
@@ -89,8 +91,10 @@
providers.add(p);
providersNames.put(p.getName(), p);
initServiceInfo(p);
- } catch (Exception e) { // ignore
- }
+ } catch (ClassNotFoundException e) { // ignore Exceptions
+ } catch (IllegalAccessException e) {
+ } catch (InstantiationException e) {
+ }
}
Engine.door.renumProviders();
}
@@ -166,21 +170,21 @@
String key;
String type;
String alias;
- StringBuffer sb = new StringBuffer(128);
+ StringBuilder sb = new StringBuilder(128);
for (Iterator<Provider.Service> it1 = p.getServices().iterator(); it1.hasNext();) {
serv = it1.next();
type = serv.getType();
sb.delete(0, sb.length());
key = sb.append(type).append(".").append( //$NON-NLS-1$
- serv.getAlgorithm().toUpperCase()).toString();
+ Util.toUpperCase(serv.getAlgorithm())).toString();
if (!services.containsKey(key)) {
services.put(key, serv);
}
for (Iterator<String> it2 = Engine.door.getAliases(serv); it2.hasNext();) {
alias = it2.next();
sb.delete(0, sb.length());
- key = sb.append(type).append(".").append(alias.toUpperCase()) //$NON-NLS-1$
+ key = sb.append(type).append(".").append(Util.toUpperCase(alias)) //$NON-NLS-1$
.toString();
if (!services.containsKey(key)) {
services.put(key, serv);
diff --git a/security/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequestInfo.java b/security/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequestInfo.java
index 7c57e93..2f31131 100644
--- a/security/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequestInfo.java
+++ b/security/src/main/java/org/apache/harmony/security/pkcs10/CertificationRequestInfo.java
@@ -115,7 +115,7 @@
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("-- CertificationRequestInfo:"); //$NON-NLS-1$
res.append("\n version: "); //$NON-NLS-1$
res.append(version);
diff --git a/security/src/main/java/org/apache/harmony/security/pkcs7/ContentInfo.java b/security/src/main/java/org/apache/harmony/security/pkcs7/ContentInfo.java
index 0249055..2c129e2 100644
--- a/security/src/main/java/org/apache/harmony/security/pkcs7/ContentInfo.java
+++ b/security/src/main/java/org/apache/harmony/security/pkcs7/ContentInfo.java
@@ -93,7 +93,7 @@
}
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("==== ContentInfo:"); //$NON-NLS-1$
res.append("\n== ContentType (OID): "); //$NON-NLS-1$
for (int i = 0; i< oid.length; i++) {
diff --git a/security/src/main/java/org/apache/harmony/security/pkcs7/SignedData.java b/security/src/main/java/org/apache/harmony/security/pkcs7/SignedData.java
index 718d3d3..2f9e99d 100644
--- a/security/src/main/java/org/apache/harmony/security/pkcs7/SignedData.java
+++ b/security/src/main/java/org/apache/harmony/security/pkcs7/SignedData.java
@@ -105,7 +105,7 @@
}
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("---- SignedData:"); //$NON-NLS-1$
res.append("\nversion: "); //$NON-NLS-1$
res.append(version);
diff --git a/security/src/main/java/org/apache/harmony/security/pkcs7/SignerInfo.java b/security/src/main/java/org/apache/harmony/security/pkcs7/SignerInfo.java
index 05a0c7a..9235577 100644
--- a/security/src/main/java/org/apache/harmony/security/pkcs7/SignerInfo.java
+++ b/security/src/main/java/org/apache/harmony/security/pkcs7/SignerInfo.java
@@ -130,7 +130,7 @@
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("-- SignerInfo:"); //$NON-NLS-1$
res.append("\n version : "); //$NON-NLS-1$
res.append(version);
diff --git a/security/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java b/security/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java
index d53eb8a..7414e75 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/cert/X509CRLImpl.java
@@ -201,7 +201,7 @@
* from the TBSCertList structure and converts them to the
* X509CRLEntryImpl objects
*/
- private void retirieveEntries() {
+ private void retrieveEntries() {
entriesRetrieved = true;
List rcerts = tbsCertList.getRevokedCertificates();
if (rcerts == null) {
@@ -243,7 +243,7 @@
throw new NullPointerException();
}
if (!entriesRetrieved) {
- retirieveEntries();
+ retrieveEntries();
}
if (entries == null) {
return null;
@@ -295,7 +295,7 @@
*/
public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) {
if (!entriesRetrieved) {
- retirieveEntries();
+ retrieveEntries();
}
if (entries == null) {
return null;
@@ -315,7 +315,7 @@
*/
public Set<? extends X509CRLEntry> getRevokedCertificates() {
if (!entriesRetrieved) {
- retirieveEntries();
+ retrieveEntries();
}
if (entries == null) {
return null;
diff --git a/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java b/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java
index 17fd6f7..f0e47d9 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertFactoryImpl.java
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.security.cert.CertPath;
@@ -446,8 +447,8 @@
// ------------------------ Staff methods ------------------------------
// ---------------------------------------------------------------------
- private static byte[] pemBegin = "-----BEGIN".getBytes(); //$NON-NLS-1$
- private static byte[] pemClose = "-----END".getBytes(); //$NON-NLS-1$
+ private static byte[] pemBegin;
+ private static byte[] pemClose;
/**
* Code describing free format for PEM boundary suffix:
* "^-----BEGIN.*\n" at the beginning, and<br>
@@ -459,8 +460,18 @@
* "^-----BEGIN CERTIFICATE-----\n" at the beginning, and<br>
* "\n-----END CERTIFICATE-----" at the end.
*/
- private static byte[] CERT_BOUND_SUFFIX =
- " CERTIFICATE-----".getBytes(); //$NON-NLS-1$
+ private static byte[] CERT_BOUND_SUFFIX;
+
+ static {
+ // Initialise statics
+ try {
+ pemBegin = "-----BEGIN".getBytes("UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
+ pemClose = "-----END".getBytes("UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
+ CERT_BOUND_SUFFIX = " CERTIFICATE-----".getBytes("UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
/**
* Method retrieves the PEM encoded data from the stream
@@ -515,9 +526,7 @@
if (boundary_suffix[i] != inStream.read()) {
throw new IOException(
Messages.getString("security.15B", //$NON-NLS-1$
- ((boundary_suffix == null)
- ? ""
- : new String(boundary_suffix)))); //$NON-NLS-1$
+ new String(boundary_suffix))); //$NON-NLS-1$
}
}
// read new line characters
@@ -574,9 +583,7 @@
if (boundary_suffix[i] != inStream.read()) {
throw new IOException(
Messages.getString("security.15B1", //$NON-NLS-1$
- ((boundary_suffix == null)
- ? ""
- : new String(boundary_suffix)))); //$NON-NLS-1$
+ new String(boundary_suffix))); //$NON-NLS-1$
}
}
}
@@ -933,3 +940,5 @@
}
}
+
+
diff --git a/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java b/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java
index 2234ce4..83b9944 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertPathImpl.java
@@ -313,7 +313,7 @@
/**
* ASN.1 DER Encoder/Decoder for PkiPath structure.
*/
- public static ASN1SequenceOf ASN1 =
+ public static final ASN1SequenceOf ASN1 =
new ASN1SequenceOf(ASN1Any.getInstance()) {
/**
diff --git a/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java b/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java
index af314ef..42d3043 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java
@@ -38,7 +38,7 @@
public class DSAKeyFactoryImpl extends KeyFactorySpi {
/**
- * The method generates a DSAPrivateKey object from the provided key specification.
+ * This method generates a DSAPrivateKey object from the provided key specification.
*
* @param
* keySpec - the specification (key material) for the DSAPrivateKey.
@@ -66,7 +66,7 @@
}
/**
- * The method generates a DSAPublicKey object from the provided key specification.
+ * This method generates a DSAPublicKey object from the provided key specification.
*
* @param
* keySpec - the specification (key material) for the DSAPublicKey.
@@ -92,28 +92,23 @@
}
throw new InvalidKeySpecException(Messages.getString("security.19D")); //$NON-NLS-1$
}
-
+
/**
- * The method returns a specification (key material) of the given key object.
- * 'keySpec' identifies the specification class
- * in which the key material should be returned.
- *
- * If it is DSAPublicKeySpec.class, the key material should be returned
- * in an instance of the DSAPublicKeySpec class;
- * if it is DSAPrivateKeySpec.class, the key material should be returned
- * in an instance of the DSAPrivateKeySpec class.
- *
- * @param
- * key - either DSAPrivateKey or DSAPublicKey
- * @param
- * keySpec - either DSAPublicKeySpec.class or DSAPublicKeySpec.class
- *
- * @return
- * either DSAPublicKeySpec object or DSAPublicKeySpec object
- *
+ * This method returns a specification for the supplied key.
+ *
+ * The specification will be returned in the form of an object of the type
+ * specified by keySpec.
+ *
+ * @param key -
+ * either DSAPrivateKey or DSAPublicKey
+ * @param keySpec -
+ * either DSAPrivateKeySpec.class or DSAPublicKeySpec.class
+ *
+ * @return either a DSAPrivateKeySpec or a DSAPublicKeySpec
+ *
* @throws InvalidKeySpecException
- * if "keySpec" is not s specification for DSAPublicKey or DSAPrivateKey
- *
+ * if "keySpec" is not a specification for DSAPublicKey or
+ * DSAPrivateKey
*/
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
throws InvalidKeySpecException {
diff --git a/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java b/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java
index 17af038..291d69e 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java
@@ -27,6 +27,7 @@
package org.apache.harmony.security.provider.crypto;
import java.io.IOException;
+import java.io.NotActiveException;
import java.math.BigInteger;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
@@ -53,9 +54,9 @@
*/
private static final long serialVersionUID = -4716227614104950081L;
- private BigInteger x;
+ private BigInteger x, g, p, q;
- private DSAParams params;
+ private transient DSAParams params;
/**
* Creates object from DSAPrivateKeySpec.
@@ -68,9 +69,9 @@
PrivateKeyInfo pki;
- BigInteger g = keySpec.getG();
- BigInteger p = keySpec.getP();
- BigInteger q = keySpec.getQ();
+ g = keySpec.getG();
+ p = keySpec.getP();
+ q = keySpec.getQ();
ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p
.toByteArray(), q.toByteArray(), g.toByteArray());
@@ -133,9 +134,10 @@
throw new InvalidKeySpecException(Messages.getString(
"security.19B", e)); //$NON-NLS-1$
}
- params = new DSAParameterSpec(new BigInteger(threeInts.p),
- new BigInteger(threeInts.q), new BigInteger(threeInts.g));
-
+ p = new BigInteger(threeInts.p);
+ q = new BigInteger(threeInts.q);
+ g = new BigInteger(threeInts.g);
+ params = new DSAParameterSpec(p, q, g);
setEncoding(encoding);
/*
@@ -153,5 +155,10 @@
public DSAParams getParams() {
return params;
}
+
+ private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ params = new DSAParameterSpec(p, q, g);
+ }
}
diff --git a/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java b/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java
index bd1efdd..f4bb13d 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java
@@ -29,6 +29,7 @@
package org.apache.harmony.security.provider.crypto;
import java.io.IOException;
+import java.io.NotActiveException;
import java.math.BigInteger;
@@ -45,12 +46,6 @@
import org.apache.harmony.security.x509.SubjectPublicKeyInfo;
import org.apache.harmony.security.asn1.ASN1Integer;
-//import org.apache.harmony.security.asn1.ASN1Sequence;
-//import org.apache.harmony.security.asn1.ASN1Type;
-//import org.apache.harmony.security.asn1.BerInputStream;
-//import org.apache.harmony.security.asn1.ASN1BitString;
-//import org.apache.harmony.security.asn1.BitString;
-//import org.apache.harmony.security.asn1.ASN1OctetString;
import org.apache.harmony.security.internal.nls.Messages;
@@ -67,9 +62,9 @@
*/
private static final long serialVersionUID = -2279672131310978336L;
- private BigInteger y;
+ private BigInteger y, g, p, q;
- private DSAParams params;
+ private transient DSAParams params;
/**
* Creates object from DSAPublicKeySpec.
@@ -82,9 +77,9 @@
SubjectPublicKeyInfo spki;
- BigInteger p = keySpec.getP();
- BigInteger q = keySpec.getQ();
- BigInteger g = keySpec.getG();
+ p = keySpec.getP();
+ q = keySpec.getQ();
+ g = keySpec.getG();
ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p
.toByteArray(), q.toByteArray(), g.toByteArray());
@@ -148,8 +143,10 @@
throw new InvalidKeySpecException(Messages.getString(
"security.19B", e)); //$NON-NLS-1$
}
- params = (DSAParams) (new DSAParameterSpec(new BigInteger(threeInts.p),
- new BigInteger(threeInts.q), new BigInteger(threeInts.g)));
+ p = new BigInteger(threeInts.p);
+ q = new BigInteger(threeInts.q);
+ g = new BigInteger(threeInts.g);
+ params = (DSAParams) (new DSAParameterSpec(p, q, g));
setEncoding(encoding);
@@ -176,5 +173,10 @@
public DSAParams getParams() {
return params;
}
+
+ private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ params = new DSAParameterSpec(p, q, g);
+ }
}
diff --git a/security/src/main/java/org/apache/harmony/security/provider/crypto/RandomBitsSupplier.java b/security/src/main/java/org/apache/harmony/security/provider/crypto/RandomBitsSupplier.java
index 14db652..e3fde7f 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/crypto/RandomBitsSupplier.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/crypto/RandomBitsSupplier.java
@@ -35,7 +35,7 @@
* The static class providing access on Linux platform
* to system means for generating true random bits. <BR>
*
- * The source for true random bits is one of Linux's devices "/dev/urandom/" or
+ * The source for true random bits is one of Linux's devices "/dev/urandom" or
* "/dev/random" depends on which one is available; if both the first is used. <BR>
*
* If no device available the service is not available,
@@ -69,7 +69,7 @@
/**
* value of field is "true" only if a device is available
*/
- private static boolean serviceAvailable;
+ private static boolean serviceAvailable = false;
static {
@@ -86,16 +86,26 @@
bis = new FileInputStream(file);
// END android-modified
randomFile = file;
+ serviceAvailable = true;
return null;
}
} catch (FileNotFoundException e) {
}
}
+
+ // BEGIN android-removed
+// // If we have come out of the above loop, then we have been unable to
+// // access /dev/*random, so try to fall back to using the system random() API
+// try {
+// System.loadLibrary(LIBRARY_NAME);
+// serviceAvailable = true;
+// } catch (UnsatisfiedLinkError e) {
+// serviceAvailable = false;
+// }
return null;
}
}
);
- serviceAvailable = (bis != null);
}
@@ -108,12 +118,12 @@
/**
- * On the Linux platform with "random" devices available,
+ * On platforms with "random" devices available,
* the method reads random bytes from the device. <BR>
*
* In case of any runtime failure ProviderException gets thrown.
*/
- private static synchronized byte[] getLinuxRandomBits(int numBytes) {
+ private static synchronized byte[] getUnixDeviceRandom(int numBytes) {
byte[] bytes = new byte[numBytes];
@@ -128,7 +138,6 @@
// the below case should not occur because /dev/random or /dev/urandom is a special file
// hence, if it is happened there is some internal problem
- //
if ( bytesRead == -1 ) {
throw new ProviderException(
Messages.getString("security.193") ); //$NON-NLS-1$
@@ -146,7 +155,6 @@
// actually there should be no IOException because device is a special file;
// hence, there is either some internal problem or, for instance,
// device was removed in runtime, or something else
- //
throw new ProviderException(
Messages.getString("security.194"), e ); //$NON-NLS-1$
}
@@ -154,6 +162,17 @@
}
+ // BEGIN android-removed
+// /**
+// * On platforms with no "random" devices available, this native
+// * method uses system API calls to generate random numbers<BR>
+// *
+// * In case of any runtime failure ProviderException gets thrown.
+// */
+// private static native synchronized boolean getUnixSystemRandom(byte[] randomBits, int numBytes);
+ // END android-removed
+
+
/**
* The method returns byte array of requested length provided service is available.
* ProviderException gets thrown otherwise.
@@ -171,12 +190,15 @@
throw new IllegalArgumentException(Messages.getString("security.195", numBytes)); //$NON-NLS-1$
}
+ // We have been unable to get a random device or fall back to the
+ // native security module code - throw an exception.
if ( !serviceAvailable ) {
throw new ProviderException(
Messages.getString("security.196")); //$NON-NLS-1$
}
- return getLinuxRandomBits(numBytes);
+ // BEGIN android-changed
+ return getUnixDeviceRandom(numBytes);
+ // END android-changed
}
-
}
diff --git a/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_Data.java b/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_Data.java
index 6e9ecb8..7294361 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_Data.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1_Data.java
@@ -82,10 +82,12 @@
static final int DIGEST_LENGTH = 20;
- /**
- * name of native library to use on Windows platform
- */
- static final String LIBRARY_NAME = "hysecurity"; //$NON-NLS-1$
+ // BEGIN android-removed
+// /**
+// * name of native library to use on Windows platform
+// */
+// static final String LIBRARY_NAME = "hysecurity"; //$NON-NLS-1$
+ // END android-removed
/**
diff --git a/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java b/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java
index 576ac76..b7b9c98 100644
--- a/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java
+++ b/security/src/main/java/org/apache/harmony/security/provider/crypto/SHA1withDSA_SignatureImpl.java
@@ -83,7 +83,7 @@
DSAParams params;
// parameters and private key
- BigInteger p, q, g, x;
+ BigInteger p, q, x;
int n;
@@ -95,7 +95,6 @@
params = ((DSAPrivateKey) privateKey).getParams();
p = params.getP();
q = params.getQ();
- g = params.getG();
x = ((DSAPrivateKey) privateKey).getX();
// checks described in DSA standard
@@ -129,7 +128,7 @@
throws InvalidKeyException {
// parameters and public key
- BigInteger p, q, g, y;
+ BigInteger p, q, y;
int n1;
@@ -141,7 +140,6 @@
DSAParams params = ((DSAPublicKey) publicKey).getParams();
p = params.getP();
q = params.getQ();
- g = params.getG();
y = ((DSAPublicKey) publicKey).getY();
// checks described in DSA standard
@@ -207,7 +205,6 @@
// various byte array being used in computing signature
byte randomBytes[];
- byte digest[];
byte rBytes[], sBytes[], signature[];
int n, n1, n2;
diff --git a/security/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java b/security/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java
index f1f5bce..bc84c01 100644
--- a/security/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java
+++ b/security/src/main/java/org/apache/harmony/security/utils/AlgNameMapper.java
@@ -29,43 +29,13 @@
import java.util.Set;
import java.util.Map.Entry;
+import org.apache.harmony.security.Util;
import org.apache.harmony.security.asn1.ObjectIdentifier;
/**
- * Provides Algorithm Name to OID
- * and OID to Algorithm Name mappings.
- * Some known mappings are hardcoded.
- * Tries to obtain additional mappings
- * from installed providers during initialization.
- *
- * Hardcoded mappings
- * (source: http://asn1.elibel.tm.fr):
- *
- * 1.2.840.10040.4.1 -> DSA
- *
- * 1.2.840.113549.1.1.1 -> RSA
- *
- * 1.2.840.113549.1.3.1 -> DiffieHellman
- *
- * 1.2.840.113549.1.5.3 -> PBEWithMD5AndDES
- *
- * 1.2.840.113549.1.12.1.3 -> pbeWithSHAAnd3-KeyTripleDES-CBC
- * 1.2.840.113549.1.12.1.3 -> PBEWithSHA1AndDESede
- * 1.2.840.113549.1.12.1.3 -> PBEWithSHA1AndTripleDES
- *
- * 1.2.840.113549.1.12.1.6 -> pbeWithSHAAnd40BitRC2-CBC
- * 1.2.840.113549.1.12.1.6 -> PBEWithSHA1AndRC2_40
- *
- * 1.2.840.113549.3.2 -> RC2-CBC
- * 1.2.840.113549.3.3 -> RC2-EBC
- * 1.2.840.113549.3.4 -> RC4
- * 1.2.840.113549.3.5 -> RC4WithMAC
- * 1.2.840.113549.3.6 -> DESx-CBC
- * 1.2.840.113549.3.7 -> TripleDES-CBC
- * 1.2.840.113549.3.8 -> rc5CBC
- * 1.2.840.113549.3.9 -> RC5-CBC
- * 1.2.840.113549.3.10 -> DESCDMF (CDMFCBCPad)
- *
+ * Provides Algorithm Name to OID and OID to Algorithm Name mappings. Some known
+ * mappings are hardcoded. Tries to obtain additional mappings from installed
+ * providers during initialization.
*/
public class AlgNameMapper {
@@ -114,7 +84,7 @@
static {
for (String[] element : knownAlgMappings) {
- String algUC = element[1].toUpperCase();
+ String algUC = Util.toUpperCase(element[1]);
alg2OidMap.put(algUC, element[0]);
oid2AlgMap.put(element[0], algUC);
// map upper case alg name to its original name
@@ -144,7 +114,7 @@
*/
public static String map2OID(String algName) {
// alg2OidMap map contains upper case keys
- return alg2OidMap.get(algName.toUpperCase());
+ return alg2OidMap.get(Util.toUpperCase(algName));
}
/**
@@ -167,7 +137,7 @@
* @return algorithm name
*/
public static String getStandardName(String algName) {
- return algAliasesMap.get(algName.toUpperCase());
+ return algAliasesMap.get(Util.toUpperCase(algName));
}
// Searches given provider for mappings like
@@ -184,7 +154,7 @@
if (key.startsWith(keyPrfix2find)) {
String alias = key.substring(keyPrfix2find.length());
String alg = (String)me.getValue();
- String algUC = alg.toUpperCase();
+ String algUC = Util.toUpperCase(alg);
if (isOID(alias)) {
if (alias.startsWith("OID.")) { //$NON-NLS-1$
alias = alias.substring(4);
@@ -203,8 +173,8 @@
algAliasesMap.put(algUC, alg);
}
// Do not override known standard names
- } else if (!algAliasesMap.containsKey(alias.toUpperCase())) {
- algAliasesMap.put(alias.toUpperCase(), alg);
+ } else if (!algAliasesMap.containsKey(Util.toUpperCase(alias))) {
+ algAliasesMap.put(Util.toUpperCase(alias), alg);
}
}
}
@@ -240,7 +210,7 @@
* @return Internal maps String representation
*/
public static String dump() {
- StringBuffer sb = new StringBuffer("alg2OidMap: "); //$NON-NLS-1$
+ StringBuilder sb = new StringBuilder("alg2OidMap: "); //$NON-NLS-1$
sb.append(alg2OidMap);
sb.append("\noid2AlgMap: "); //$NON-NLS-1$
sb.append(oid2AlgMap);
diff --git a/security/src/main/java/org/apache/harmony/security/utils/ObjectIdentifier.java b/security/src/main/java/org/apache/harmony/security/utils/ObjectIdentifier.java
index 517e096..2a19656 100644
--- a/security/src/main/java/org/apache/harmony/security/utils/ObjectIdentifier.java
+++ b/security/src/main/java/org/apache/harmony/security/utils/ObjectIdentifier.java
@@ -158,7 +158,7 @@
*/
public String toString() {
if (soid == null) {
- StringBuffer sb = new StringBuffer(4 * oid.length);
+ StringBuilder sb = new StringBuilder(4 * oid.length);
for (int i = 0; i < oid.length - 1; ++i) {
sb.append(oid[i]);
diff --git a/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java b/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java
index 34337eb..63434893 100644
--- a/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java
+++ b/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValue.java
@@ -28,6 +28,7 @@
import java.util.Iterator;
import javax.security.auth.x500.X500Principal;
+import java.io.UnsupportedEncodingException;
import org.apache.harmony.security.asn1.ASN1Constants;
import org.apache.harmony.security.asn1.ASN1Oid;
@@ -38,6 +39,7 @@
import org.apache.harmony.security.asn1.BerOutputStream;
import org.apache.harmony.security.internal.nls.Messages;
import org.apache.harmony.security.utils.ObjectIdentifier;
+import org.apache.harmony.security.Util;
/**
@@ -284,7 +286,7 @@
this.oid = thisOid;
} else {
- this.oid = (ObjectIdentifier) KNOWN_NAMES.get(sOid.toUpperCase());
+ this.oid = (ObjectIdentifier) KNOWN_NAMES.get(Util.toUpperCase(sOid));
if (this.oid == null) {
throw new IOException(Messages.getString("security.178", sOid)); //$NON-NLS-1$
}
@@ -301,7 +303,7 @@
public void appendName(String attrFormat, StringBuffer buf) {
boolean hexFormat = false;
- if (attrFormat == X500Principal.RFC1779) {
+ if (X500Principal.RFC1779.equals(attrFormat)) {
if (RFC1779_NAMES == oid.getGroup()) {
buf.append(oid.getName());
} else {
@@ -311,7 +313,7 @@
buf.append('=');
if (value.escapedString == value.getHexString()) {
//FIXME all chars in upper case
- buf.append(value.getHexString().toUpperCase());
+ buf.append(Util.toUpperCase(value.getHexString()));
} else if (value.escapedString.length() != value.rawString.length()) {
// was escaped
value.appendQEString(buf);
@@ -324,7 +326,7 @@
if (RFC1779_NAMES == group || RFC2253_NAMES == group) {
buf.append(oid.getName());
- if (attrFormat == X500Principal.CANONICAL) {
+ if (X500Principal.CANONICAL.equals(attrFormat)) {
// only PrintableString and UTF8String in string format
// all others are output in hex format
// BEGIN android-changed
@@ -348,7 +350,7 @@
if (hexFormat) {
buf.append(value.getHexString());
} else {
- if (attrFormat == X500Principal.CANONICAL) {
+ if (X500Principal.CANONICAL.equals(attrFormat)) {
buf.append(value.makeCanonical());
} else {
buf.append(value.escapedString);
@@ -387,7 +389,7 @@
*
*/
- public static ASN1Type AttributeValue = new ASN1Type(
+ public static final ASN1Type attributeValue = new ASN1Type(
ASN1Constants.TAG_PRINTABLESTRING) {
public boolean checkTag(int tag) {
@@ -452,7 +454,11 @@
av.bytes = (byte[]) out.content;
out.content = av;
} else {
- av.bytes = av.rawString.getBytes();
+ try {
+ av.bytes = av.rawString.getBytes("UTF-8"); //$NON-NLS-1$
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.getMessage());
+ }
out.length = av.bytes.length;
}
}
@@ -476,7 +482,7 @@
};
public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
- ASN1Oid.getInstance(), AttributeValue }) {
+ ASN1Oid.getInstance(), attributeValue }) {
protected Object getDecodedObject(BerInputStream in) throws IOException {
Object[] values = (Object[]) in.content;
@@ -541,4 +547,4 @@
}
return intHash & 0x7FFFFFFF; // only positive
}
-}
\ No newline at end of file
+}
diff --git a/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java b/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java
index 8844035..30d71e7 100644
--- a/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java
+++ b/security/src/main/java/org/apache/harmony/security/x501/AttributeTypeAndValueComparator.java
@@ -22,6 +22,7 @@
package org.apache.harmony.security.x501;
+import java.io.Serializable;
import java.util.Comparator;
import org.apache.harmony.security.utils.ObjectIdentifier;
@@ -30,9 +31,11 @@
* AttributeTypeAndValue comparator
*
*/
-public class AttributeTypeAndValueComparator implements Comparator {
+public class AttributeTypeAndValueComparator implements Comparator, Serializable {
- /**
+ private static final long serialVersionUID = -1286471842007103132L;
+
+ /**
* compares two AttributeTypeAndValues
*
* @param obj1
@@ -63,14 +66,7 @@
return compateOids(atav1.getType(), atav2.getType());
}
-
- /**
- * @return false
- */
- public boolean equals(Object obj) {
- return false;
- }
-
+
/**
* compares two Object identifiers
*
diff --git a/security/src/main/java/org/apache/harmony/security/x501/AttributeValue.java b/security/src/main/java/org/apache/harmony/security/x501/AttributeValue.java
index 51f9725..0844c5e 100644
--- a/security/src/main/java/org/apache/harmony/security/x501/AttributeValue.java
+++ b/security/src/main/java/org/apache/harmony/security/x501/AttributeValue.java
@@ -126,7 +126,7 @@
}
}
- StringBuffer buf = new StringBuffer(encoded.length * 2 + 1);
+ StringBuilder buf = new StringBuilder(encoded.length * 2 + 1);
buf.append('#');
for (int i = 0, c; i < encoded.length; i++) {
@@ -180,7 +180,7 @@
if (length == 0) {
return name;
}
- StringBuffer buf = new StringBuffer(length * 2);
+ StringBuilder buf = new StringBuilder(length * 2);
for (int index = 0; index < length; index++) {
@@ -223,7 +223,7 @@
if (length == 0) {
return rawString;
}
- StringBuffer buf = new StringBuffer(length * 2);
+ StringBuilder buf = new StringBuilder(length * 2);
int index = 0;
if (rawString.charAt(0) == '#') {
diff --git a/security/src/main/java/org/apache/harmony/security/x501/Name.java b/security/src/main/java/org/apache/harmony/security/x501/Name.java
index 836342e..ae08671 100644
--- a/security/src/main/java/org/apache/harmony/security/x501/Name.java
+++ b/security/src/main/java/org/apache/harmony/security/x501/Name.java
@@ -118,21 +118,21 @@
//
// check X500Principal constants first
//
- if (format == X500Principal.RFC1779) {
+ if (X500Principal.RFC1779.equals(format)) {
if (rfc1779String == null) {
rfc1779String = getName0(format);
}
return rfc1779String;
- } else if (format == X500Principal.RFC2253) {
+ } else if (X500Principal.RFC2253.equals(format)) {
if (rfc2253String == null) {
rfc2253String = getName0(format);
}
return rfc2253String;
- } else if (format == X500Principal.CANONICAL) {
+ } else if (X500Principal.CANONICAL.equals(format)) {
if (canonicalString == null) {
canonicalString = getName0(format);
@@ -217,7 +217,7 @@
}
String sName = name.toString();
- if (format == X500Principal.CANONICAL) {
+ if (X500Principal.CANONICAL.equals(format)) {
sName = sName.toLowerCase(Locale.US);
}
return sName;
diff --git a/security/src/main/java/org/apache/harmony/security/x509/AccessDescription.java b/security/src/main/java/org/apache/harmony/security/x509/AccessDescription.java
index bc8fd28..69b9258 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/AccessDescription.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/AccessDescription.java
@@ -70,7 +70,7 @@
}
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("\n-- AccessDescription:"); //$NON-NLS-1$
res.append("\naccessMethod: "); //$NON-NLS-1$
res.append(accessMethod);
diff --git a/security/src/main/java/org/apache/harmony/security/x509/AlgorithmIdentifier.java b/security/src/main/java/org/apache/harmony/security/x509/AlgorithmIdentifier.java
index 70dba99..728fd6a 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/AlgorithmIdentifier.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/AlgorithmIdentifier.java
@@ -143,6 +143,11 @@
: Arrays.equals(parameters, algid.parameters));
}
+ public int hashCode() {
+ return algorithm.hashCode() * 37 +
+ (parameters != null ? parameters.hashCode() : 0);
+ }
+
/**
* Places the string representation into the StringBuffer object.
*/
diff --git a/security/src/main/java/org/apache/harmony/security/x509/AuthorityKeyIdentifier.java b/security/src/main/java/org/apache/harmony/security/x509/AuthorityKeyIdentifier.java
index 1cf9c3e..3de59fb 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/AuthorityKeyIdentifier.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/AuthorityKeyIdentifier.java
@@ -103,7 +103,7 @@
buffer.append(prefix).append("]\n"); //$NON-NLS-1$
}
- public static ASN1Type ASN1 = new ASN1Sequence(
+ public static final ASN1Type ASN1 = new ASN1Sequence(
new ASN1Type[] {
new ASN1Implicit(0, ASN1OctetString.getInstance()),
new ASN1Implicit(1, GeneralNames.ASN1),
diff --git a/security/src/main/java/org/apache/harmony/security/x509/BasicConstraints.java b/security/src/main/java/org/apache/harmony/security/x509/BasicConstraints.java
index 10b3156..edbf13e 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/BasicConstraints.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/BasicConstraints.java
@@ -105,7 +105,7 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] {
+ public static final ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] {
ASN1Boolean.getInstance(), ASN1Integer.getInstance() }) {
{
setDefault(Boolean.FALSE, 0);
diff --git a/security/src/main/java/org/apache/harmony/security/x509/CRLNumber.java b/security/src/main/java/org/apache/harmony/security/x509/CRLNumber.java
index 85cbea0..db2480e 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/CRLNumber.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/CRLNumber.java
@@ -84,5 +84,5 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1Type ASN1 = ASN1Integer.getInstance();
+ public static final ASN1Type ASN1 = ASN1Integer.getInstance();
}
diff --git a/security/src/main/java/org/apache/harmony/security/x509/CertificateIssuer.java b/security/src/main/java/org/apache/harmony/security/x509/CertificateIssuer.java
index 3a31734..d6ab760 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/CertificateIssuer.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/CertificateIssuer.java
@@ -87,7 +87,7 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] {
+ public static final ASN1Type ASN1 = new ASN1Sequence(new ASN1Type[] {
GeneralName.ASN1
}) {
public Object getDecodedObject(BerInputStream in) {
diff --git a/security/src/main/java/org/apache/harmony/security/x509/DNParser.java b/security/src/main/java/org/apache/harmony/security/x509/DNParser.java
index 730f7df..5870bcd 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/DNParser.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/DNParser.java
@@ -293,6 +293,9 @@
case '#':
case ';':
case ' ':
+ case '*':
+ case '%':
+ case '_':
//FIXME: escaping is allowed only for leading or trailing space char
return chars[pos];
default:
diff --git a/security/src/main/java/org/apache/harmony/security/x509/ExtendedKeyUsage.java b/security/src/main/java/org/apache/harmony/security/x509/ExtendedKeyUsage.java
index 69e9cee..4eacbd5 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/ExtendedKeyUsage.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/ExtendedKeyUsage.java
@@ -109,7 +109,7 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1Type ASN1 =
+ public static final ASN1Type ASN1 =
new ASN1SequenceOf(new ASN1Oid() {
public Object getDecodedObject(BerInputStream in)
diff --git a/security/src/main/java/org/apache/harmony/security/x509/Extension.java b/security/src/main/java/org/apache/harmony/security/x509/Extension.java
index 833f2fe..86e7a45 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/Extension.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/Extension.java
@@ -58,34 +58,34 @@
// constants: the extension OIDs
// certificate extensions:
- public static final int[] SUBJ_DIRECTORY_ATTRS = {2, 5, 29, 9};
- public static final int[] SUBJ_KEY_ID = {2, 5, 29, 14};
- public static final int[] KEY_USAGE = {2, 5, 29, 15};
- public static final int[] PRIVATE_KEY_USAGE_PERIOD = {2, 5, 29, 16};
- public static final int[] SUBJECT_ALT_NAME = {2, 5, 29, 17};
- public static final int[] ISSUER_ALTERNATIVE_NAME = {2, 5, 29, 18};
- public static final int[] BASIC_CONSTRAINTS = {2, 5, 29, 19};
- public static final int[] NAME_CONSTRAINTS = {2, 5, 29, 30};
- public static final int[] CRL_DISTR_POINTS = {2, 5, 29, 31};
- public static final int[] CERTIFICATE_POLICIES = {2, 5, 29, 32};
- public static final int[] POLICY_MAPPINGS = {2, 5, 29, 33};
- public static final int[] AUTH_KEY_ID = {2, 5, 29, 35};
- public static final int[] POLICY_CONSTRAINTS = {2, 5, 29, 36};
- public static final int[] EXTENDED_KEY_USAGE = {2, 5, 29, 37};
- public static final int[] FRESHEST_CRL = {2, 5, 29, 46};
- public static final int[] INHIBIT_ANY_POLICY = {2, 5, 29, 54};
- public static final int[] AUTHORITY_INFO_ACCESS =
+ static final int[] SUBJ_DIRECTORY_ATTRS = {2, 5, 29, 9};
+ static final int[] SUBJ_KEY_ID = {2, 5, 29, 14};
+ static final int[] KEY_USAGE = {2, 5, 29, 15};
+ static final int[] PRIVATE_KEY_USAGE_PERIOD = {2, 5, 29, 16};
+ static final int[] SUBJECT_ALT_NAME = {2, 5, 29, 17};
+ static final int[] ISSUER_ALTERNATIVE_NAME = {2, 5, 29, 18};
+ static final int[] BASIC_CONSTRAINTS = {2, 5, 29, 19};
+ static final int[] NAME_CONSTRAINTS = {2, 5, 29, 30};
+ static final int[] CRL_DISTR_POINTS = {2, 5, 29, 31};
+ static final int[] CERTIFICATE_POLICIES = {2, 5, 29, 32};
+ static final int[] POLICY_MAPPINGS = {2, 5, 29, 33};
+ static final int[] AUTH_KEY_ID = {2, 5, 29, 35};
+ static final int[] POLICY_CONSTRAINTS = {2, 5, 29, 36};
+ static final int[] EXTENDED_KEY_USAGE = {2, 5, 29, 37};
+ static final int[] FRESHEST_CRL = {2, 5, 29, 46};
+ static final int[] INHIBIT_ANY_POLICY = {2, 5, 29, 54};
+ static final int[] AUTHORITY_INFO_ACCESS =
{1, 3, 6, 1, 5, 5, 7, 1, 1};
- public static final int[] SUBJECT_INFO_ACCESS =
+ static final int[] SUBJECT_INFO_ACCESS =
{1, 3, 6, 1, 5, 5, 7, 1, 11};
// crl extensions:
- public static final int[] ISSUING_DISTR_POINT = {2, 5, 29, 28};
+ static final int[] ISSUING_DISTR_POINT = {2, 5, 29, 28};
// crl entry extensions:
- public static final int[] CRL_NUMBER = {2, 5, 29, 20};
- public static final int[] CERTIFICATE_ISSUER = {2, 5, 29, 29};
- public static final int[] INVALIDITY_DATE = {2, 5, 29, 24};
- public static final int[] REASON_CODE = {2, 5, 29, 21};
- public static final int[] ISSUING_DISTR_POINTS = {2, 5, 29, 28};
+ static final int[] CRL_NUMBER = {2, 5, 29, 20};
+ static final int[] CERTIFICATE_ISSUER = {2, 5, 29, 29};
+ static final int[] INVALIDITY_DATE = {2, 5, 29, 24};
+ static final int[] REASON_CODE = {2, 5, 29, 21};
+ static final int[] ISSUING_DISTR_POINTS = {2, 5, 29, 28};
// the value of extnID field of the structure
private final int[] extnID;
@@ -238,6 +238,10 @@
&& (critical == extn.critical)
&& Arrays.equals(extnValue, extn.extnValue);
}
+
+ public int hashCode() {
+ return (extnID.hashCode() * 37 + (critical ? 1 : 0)) * 37 + extnValue.hashCode();
+ }
public ExtensionValue getDecodedExtensionValue() throws IOException {
if (!valueDecoded) {
diff --git a/security/src/main/java/org/apache/harmony/security/x509/Extensions.java b/security/src/main/java/org/apache/harmony/security/x509/Extensions.java
index e98a116..1fee6c0 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/Extensions.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/Extensions.java
@@ -386,6 +386,14 @@
);
}
+ public int hashCode() {
+ int hashcode = 0;
+ if (extensions != null) {
+ hashcode = extensions.hashCode();
+ }
+ return hashcode;
+ }
+
/**
* Places the string representation into the StringBuffer object.
*/
diff --git a/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java b/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java
index db4daaa..3b291a1 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java
@@ -328,6 +328,24 @@
return false;
}
+ public int hashCode() {
+ switch(tag) {
+ case RFC822_NAME:
+ case DNS_NAME:
+ case UR_ID:
+ case REG_ID:
+ case IP_ADDR:
+ return name.hashCode();
+ case DIR_NAME:
+ case X400_ADDR:
+ case OTHER_NAME:
+ case EDIP_NAME:
+ return getEncoded().hashCode();
+ default:
+ return super.hashCode();
+ }
+ }
+
/**
* Checks if the other general name is acceptable by this object.
* The name is acceptable if it has the same type name and its
@@ -562,16 +580,21 @@
/**
* Checks the correctness of the string representation of DNS name.
- * The correctness is checked as specified in RFC 1034 p. 10.
+ * The correctness is checked as specified in RFC 1034 p. 10, and modified
+ * by RFC 1123 (section 2.1).
*/
public static void checkDNS(String dns) throws IOException {
- byte[] bytes = dns.toLowerCase().getBytes();
+ byte[] bytes = dns.toLowerCase().getBytes("UTF-8"); //$NON-NLS-1$
// indicates if it is a first letter of the label
boolean first_letter = true;
for (int i=0; i<bytes.length; i++) {
byte ch = bytes[i];
if (first_letter) {
- if (ch > 'z' || ch < 'a') {
+ if ((bytes.length > 2) && (ch == '*') && (bytes[1] == '.')) {
+ first_letter = false;
+ continue;
+ }
+ if ((ch > 'z' || ch < 'a') && (ch < '0' || ch > '9')) {
throw new IOException(Messages.getString("security.184", //$NON-NLS-1$
(char)ch, dns));
}
@@ -585,7 +608,7 @@
if (ch == '.') {
// check the end of the previous label, it should not
// be '-' sign
- if (bytes[i-i] == '-') {
+ if (bytes[i-1] == '-') {
throw new IOException(
Messages.getString("security.186", dns)); //$NON-NLS-1$
}
@@ -619,7 +642,7 @@
* Converts OID into array of bytes.
*/
public static int[] oidStrToInts(String oid) throws IOException {
- byte[] bytes = oid.getBytes();
+ byte[] bytes = oid.getBytes("UTF-8"); //$NON-NLS-1$
if (bytes[bytes.length-1] == '.') {
throw new IOException(Messages.getString("security.56", oid)); //$NON-NLS-1$
}
@@ -673,7 +696,7 @@
}
// the resulting array
byte[] result = new byte[num_components];
- byte[] ip_bytes = ip.getBytes();
+ byte[] ip_bytes = ip.getBytes("UTF-8"); //$NON-NLS-1$
// number of address component to be read
int component = 0;
// if it is reading the second bound of a range
diff --git a/security/src/main/java/org/apache/harmony/security/x509/InfoAccessSyntax.java b/security/src/main/java/org/apache/harmony/security/x509/InfoAccessSyntax.java
index 7323124..ce5404e 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/InfoAccessSyntax.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/InfoAccessSyntax.java
@@ -86,7 +86,7 @@
}
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("\n---- InfoAccessSyntax:"); //$NON-NLS-1$
if (accessDescriptions != null) {
for (Iterator it = accessDescriptions.iterator(); it.hasNext();) {
diff --git a/security/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java b/security/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java
index bc04caf..b01fa45 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/InvalidityDate.java
@@ -82,6 +82,6 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1Type ASN1 = ASN1GeneralizedTime.getInstance();
+ public static final ASN1Type ASN1 = ASN1GeneralizedTime.getInstance();
}
diff --git a/security/src/main/java/org/apache/harmony/security/x509/IssuingDistributionPoint.java b/security/src/main/java/org/apache/harmony/security/x509/IssuingDistributionPoint.java
index aec57c3..102fe05 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/IssuingDistributionPoint.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/IssuingDistributionPoint.java
@@ -180,7 +180,7 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1Type ASN1 = new ASN1Sequence(
+ public static final ASN1Type ASN1 = new ASN1Sequence(
new ASN1Type[] {
// ASN.1 prohibits implicitly tagged CHOICE
new ASN1Explicit(0, DistributionPointName.ASN1),
diff --git a/security/src/main/java/org/apache/harmony/security/x509/ReasonCode.java b/security/src/main/java/org/apache/harmony/security/x509/ReasonCode.java
index 26b4acc..de3505d 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/ReasonCode.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/ReasonCode.java
@@ -128,6 +128,6 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1Type ASN1 = ASN1Enumerated.getInstance();
+ public static final ASN1Type ASN1 = ASN1Enumerated.getInstance();
}
diff --git a/security/src/main/java/org/apache/harmony/security/x509/ReasonFlags.java b/security/src/main/java/org/apache/harmony/security/x509/ReasonFlags.java
index 6f72dc7..842784f 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/ReasonFlags.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/ReasonFlags.java
@@ -55,7 +55,7 @@
/**
* The names of the reasons.
*/
- public static final String[] REASONS = {
+ static final String[] REASONS = {
"unused", //$NON-NLS-1$
"keyCompromise", //$NON-NLS-1$
"cACompromise", //$NON-NLS-1$
@@ -97,7 +97,7 @@
/**
* ASN.1 Encoder/Decoder.
*/
- public static ASN1BitString ASN1 =
+ public static final ASN1BitString ASN1 =
new ASN1BitString.ASN1NamedBitList(REASONS.length) {
public Object getDecodedObject(BerInputStream in) throws IOException {
return new ReasonFlags((boolean[]) super.getDecodedObject(in));
diff --git a/security/src/main/java/org/apache/harmony/security/x509/TBSCertList.java b/security/src/main/java/org/apache/harmony/security/x509/TBSCertList.java
index 597ca59..6b04d55 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/TBSCertList.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/TBSCertList.java
@@ -153,6 +153,11 @@
? rcert.crlEntryExtensions == null
: crlEntryExtensions.equals(rcert.crlEntryExtensions));
}
+
+ public int hashCode() {
+ return userCertificate.hashCode() * 37 + (int)revocationDate.getTime() / 1000
+ + (crlEntryExtensions == null ? 0 : crlEntryExtensions.hashCode());
+ }
/**
* Places the string representation of extension value
@@ -171,7 +176,7 @@
}
}
- public static ASN1Sequence ASN1 = new ASN1Sequence(
+ public static final ASN1Sequence ASN1 = new ASN1Sequence(
new ASN1Type[] {ASN1Integer.getInstance(), Time.ASN1,
Extensions.ASN1}) {
{
@@ -358,6 +363,12 @@
? tbscert.crlExtensions == null
: crlExtensions.equals(tbscert.crlExtensions));
}
+
+ public int hashCode() {
+ return ((version * 37 + signature.hashCode()) * 37
+ + issuer.getEncoded().hashCode()) * 37
+ + (int)thisUpdate.getTime() / 1000;
+ }
/**
* Places the string representation of extension value
diff --git a/security/src/main/java/org/apache/harmony/security/x509/tsp/PKIStatusInfo.java b/security/src/main/java/org/apache/harmony/security/x509/tsp/PKIStatusInfo.java
index 336a60d..b0b75a6 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/tsp/PKIStatusInfo.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/tsp/PKIStatusInfo.java
@@ -59,7 +59,7 @@
}
public String toString(){
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("-- PKIStatusInfo:");
res.append("\nPKIStatus : ");
res.append(status);
@@ -122,8 +122,7 @@
int failInfoValue = -1;
if (values[2] != null) {
- boolean[] failInfoBoolArray = (values[2] == null) ? null
- : ((BitString) values[2]).toBooleanArray();
+ boolean[] failInfoBoolArray = ((BitString) values[2]).toBooleanArray();
for (int i = 0; i < failInfoBoolArray.length; i++) {
if (failInfoBoolArray[i]) {
failInfoValue = i;
diff --git a/security/src/main/java/org/apache/harmony/security/x509/tsp/TSTInfo.java b/security/src/main/java/org/apache/harmony/security/x509/tsp/TSTInfo.java
index 4c9454e..f2aa0ee 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/tsp/TSTInfo.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/tsp/TSTInfo.java
@@ -102,7 +102,7 @@
}
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("-- TSTInfo:");
res.append("\nversion: ");
res.append(version);
diff --git a/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampReq.java b/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampReq.java
index 117ae27..5e4e6ff 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampReq.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampReq.java
@@ -82,7 +82,7 @@
}
public String toString() {
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("-- TimeStampReq:");
res.append("\nversion : ");
res.append(version);
diff --git a/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampResp.java b/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampResp.java
index ea50a2d44..af03ea5 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampResp.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/tsp/TimeStampResp.java
@@ -46,7 +46,7 @@
}
public String toString(){
- StringBuffer res = new StringBuffer();
+ StringBuilder res = new StringBuilder();
res.append("-- TimeStampResp:");
res.append("\nstatus: ");
res.append(status);
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java
index bbbe861..13ac904 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java
@@ -709,8 +709,7 @@
params = AlgorithmParameters.getInstance("DSA");
try {
params.init(enc, "DOUGLASMAWSON");
- params.init(enc, "DOUGLASMAWSON");
- fail("IOException exception expected");
+ fail("unsupported format should have raised IOException");
} catch (IOException e) {
// expected
}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java
index 2803251..089a7db 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java
@@ -47,33 +47,26 @@
suite.addTestSuite(CodeSignerTest.class);
suite.addTestSuite(CodeSource2Test.class);
suite.addTestSuite(CodeSourceTest.class);
- suite.addTestSuite(DigestException2Test.class);
suite.addTestSuite(DigestExceptionTest.class);
suite.addTestSuite(DigestInputStream2Test.class);
suite.addTestSuite(DigestInputStreamTest.class);
suite.addTestSuite(DigestOutputStreamTest.class);
- suite.addTestSuite(GeneralSecurityException2Test.class);
suite.addTestSuite(GeneralSecurityExceptionTest.class);
suite.addTestSuite(GuardedObjectTest.class);
suite.addTestSuite(Identity2Test.class);
suite.addTestSuite(IdentityScope2Test.class);
suite.addTestSuite(IdentityScopeTest.class);
- suite.addTestSuite(InvalidAlgorithmParameterException2Test.class);
suite.addTestSuite(InvalidAlgorithmParameterExceptionTest.class);
- suite.addTestSuite(InvalidKeyException2Test.class);
suite.addTestSuite(InvalidKeyExceptionTest.class);
- suite.addTestSuite(InvalidParameterException2Test.class);
suite.addTestSuite(InvalidParameterExceptionTest.class);
suite.addTestSuite(KSCallbackHandlerProtectionTest.class);
suite.addTestSuite(KSPasswordProtectionTest.class);
suite.addTestSuite(KSPrivateKeyEntryTest.class);
suite.addTestSuite(KSSecretKeyEntryTest.class);
suite.addTestSuite(KSTrustedCertificateEntryTest.class);
- suite.addTestSuite(KeyException2Test.class);
suite.addTestSuite(KeyExceptionTest.class);
suite.addTestSuite(KeyFactory2Test.class);
suite.addTestSuite(KeyFactorySpiTest.class);
- suite.addTestSuite(KeyManagementException2Test.class);
suite.addTestSuite(KeyManagementExceptionTest.class);
suite.addTestSuite(KeyPairGenerator1Test.class);
suite.addTestSuite(KeyPairGenerator2Test.class);
@@ -86,7 +79,6 @@
suite.addTestSuite(KeyStore2Test.class);
suite.addTestSuite(KeyStore3Test.class);
suite.addTestSuite(KeyStoreBuilderTest.class);
- suite.addTestSuite(KeyStoreException2Test.class);
suite.addTestSuite(KeyStoreExceptionTest.class);
suite.addTestSuite(KeyStoreSpiTest.class);
suite.addTestSuite(KeyStoreTest.class);
@@ -94,9 +86,7 @@
suite.addTestSuite(MessageDigest1Test.class);
suite.addTestSuite(MessageDigest2Test.class);
suite.addTestSuite(MessageDigestSpiTest.class);
- suite.addTestSuite(NoSuchAlgorithmException2Test.class);
suite.addTestSuite(NoSuchAlgorithmExceptionTest.class);
- suite.addTestSuite(NoSuchProviderException2Test.class);
suite.addTestSuite(NoSuchProviderExceptionTest.class);
suite.addTestSuite(Permission2Test.class);
suite.addTestSuite(PermissionCollectionTest.class);
@@ -109,7 +99,6 @@
suite.addTestSuite(PrivilegedActionExceptionTest.class);
suite.addTestSuite(ProtectionDomainTest.class);
suite.addTestSuite(Provider2Test.class);
- suite.addTestSuite(ProviderException2Test.class);
suite.addTestSuite(ProviderExceptionTest.class);
suite.addTestSuite(ProviderServiceTest.class);
suite.addTestSuite(ProviderTest.class);
@@ -121,7 +110,6 @@
suite.addTestSuite(SecurityPermissionTest.class);
suite.addTestSuite(SecurityTest.class);
suite.addTestSuite(Signature2Test.class);
- suite.addTestSuite(SignatureException2Test.class);
suite.addTestSuite(SignatureExceptionTest.class);
suite.addTestSuite(SignatureSpiTest.class);
suite.addTestSuite(SignatureTest.class);
@@ -129,7 +117,6 @@
suite.addTestSuite(SignerTest.class);
suite.addTestSuite(TimestampTest.class);
suite.addTestSuite(UnrecoverableEntryExceptionTest.class);
- suite.addTestSuite(UnrecoverableKeyException2Test.class);
suite.addTestSuite(UnrecoverableKeyExceptionTest.class);
suite.addTestSuite(UnresolvedPermissionTest.class);
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSource2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSource2Test.java
index c70bc57..fa94fbf 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSource2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSource2Test.java
@@ -128,7 +128,7 @@
public void test_hashCode() throws Exception {
URL url = new java.net.URL("file:///test");
CodeSource cs = new CodeSource(url, (Certificate[]) null);
- assertTrue("Did not get expected hashCode!", cs.hashCode() == url
+ assertEquals("Did not get expected hashCode!", cs.hashCode(), url
.hashCode());
}
@@ -163,6 +163,7 @@
(Certificate[]) null);
assertEquals("Did not get expected location!", "file:/test", cs
.getLocation().toString());
+ assertNotNull("Host should not be null", cs.getLocation().getHost());
}
/**
@@ -187,7 +188,7 @@
(Certificate[]) null);
cs2 = new CodeSource(new URL("file:/d:/somedir/"), (Certificate[]) null);
assertTrue("null host should imply host", cs1.implies(cs2));
- assertTrue("host should not imply null host", !cs2.implies(cs1));
- }
+ assertFalse("host should not imply null host", cs2.implies(cs1));
+ }
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestException2Test.java
deleted file mode 100644
index 544e618..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestException2Test.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.DigestException;
-
-@TestTargetClass(DigestException.class)
-public class DigestException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.DigestException#DigestException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "DigestException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.DigestException()
- DigestException de = new DigestException();
- assertNull("Exception with no message should yield null message.", de
- .getMessage());
- }
-
- /**
- * @tests java.security.DigestException#DigestException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Different variants of string parameter (empty, null, etc.) weren't checked",
- method = "DigestException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.security.DigestException(java.lang.String)
- DigestException de = new DigestException("Test message");
- assertEquals("Exception message is incorrect", "Test message", de
- .getMessage());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStream2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStream2Test.java
index 69a73a3..93ffe77 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStream2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStream2Test.java
@@ -19,6 +19,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -280,4 +281,4 @@
fail("Unable to find SHA-1 algorithm");
}
}
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java
index 8309c87..ca80f19 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java
@@ -651,32 +651,28 @@
method = "on",
args = {boolean.class}
)
- public void test_onZ() {
+ public void test_onZ() throws Exception {
// Test for method void java.security.DigestOutputStream.on(boolean)
- try {
- DigestOutputStream dos = new DigestOutputStream(
- new ByteArrayOutputStream(), MessageDigest
- .getInstance("SHA"));
- dos.on(false);
- byte digestArray[] = { 23, 43, 44 };
- dos.write(digestArray, 1, 1);
- byte digestResult[] = dos.getMessageDigest().digest();
- byte expected[] = { -38, 57, -93, -18, 94, 107, 75, 13, 50, 85,
- -65, -17, -107, 96, 24, -112, -81, -40, 7, 9 };
- assertTrue("Digest did not return expected result.",
- java.util.Arrays.equals(digestResult, expected));
- // now turn on processing and re-run
- dos.on(true);
- dos.write(digestArray, 1, 1);
- digestResult = dos.getMessageDigest().digest();
- byte expected1[] = { -87, 121, -17, 16, -52, 111, 106, 54, -33,
- 107, -118, 50, 51, 7, -18, 59, -78, -30, -37, -100 };
+ DigestOutputStream dos = new DigestOutputStream(
+ new ByteArrayOutputStream(), MessageDigest
+ .getInstance("SHA"));
+ dos.on(false);
+ byte digestArray[] = { 23, 43, 44 };
+ dos.write(digestArray, 1, 1);
+ byte digestResult[] = dos.getMessageDigest().digest();
+ byte expected[] = { -38, 57, -93, -18, 94, 107, 75, 13, 50, 85,
+ -65, -17, -107, 96, 24, -112, -81, -40, 7, 9 };
+ assertTrue("Digest did not return expected result.",
+ java.util.Arrays.equals(digestResult, expected));
+ // now turn on processing and re-run
+ dos.on(true);
+ dos.write(digestArray, 1, 1);
+ digestResult = dos.getMessageDigest().digest();
+ byte expected1[] = { -87, 121, -17, 16, -52, 111, 106, 54, -33,
+ 107, -118, 50, 51, 7, -18, 59, -78, -30, -37, -100 };
- assertTrue("Digest did not return expected result.",
- java.util.Arrays.equals(digestResult, expected1));
- } catch (Exception e) {
- fail("Caught exception : " + e);
- }
+ assertTrue("Digest did not return expected result.",
+ java.util.Arrays.equals(digestResult, expected1));
}
/**
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/GeneralSecurityException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/GeneralSecurityException2Test.java
deleted file mode 100644
index 3647115..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/GeneralSecurityException2Test.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.GeneralSecurityException;
-
-@TestTargetClass(GeneralSecurityException.class)
-public class GeneralSecurityException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.GeneralSecurityException#GeneralSecurityException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "GeneralSecurityException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.GeneralSecurityException()
- GeneralSecurityException e = new GeneralSecurityException();
- assertNotNull("Constructor returned null instance", e);
- assertEquals("Failed toString test for constructed instance", "java.security.GeneralSecurityException", e
- .toString());
- }
-
- /**
- * @tests java.security.GeneralSecurityException#GeneralSecurityException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verifies non null parameter only",
- method = "GeneralSecurityException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.security.GeneralSecurityException(java.lang.String)
- GeneralSecurityException e = new GeneralSecurityException(
- "test message");
- assertNotNull("Constructor returned null instance", e);
- assertEquals("Failed toString test for constructed instance",
- "java.security.GeneralSecurityException: test message", e
- .toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
index 55e2fd2..865bbea 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
@@ -20,6 +20,7 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
import java.security.Certificate;
import java.security.Identity;
import java.security.IdentityScope;
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidAlgorithmParameterException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidAlgorithmParameterException2Test.java
deleted file mode 100644
index dafdb38..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidAlgorithmParameterException2Test.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.InvalidAlgorithmParameterException;
-
-@TestTargetClass(InvalidAlgorithmParameterException.class)
-public class InvalidAlgorithmParameterException2Test extends
- junit.framework.TestCase {
-
- /**
- * @tests java.security.InvalidAlgorithmParameterException#InvalidAlgorithmParameterException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "InvalidAlgorithmParameterException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.InvalidAlgorithmParameterException()
- InvalidAlgorithmParameterException e = new InvalidAlgorithmParameterException();
- assertNotNull("Constructor returned null instance", e);
- assertEquals("Failed toString test for constructed instance",
- "java.security.InvalidAlgorithmParameterException", e
- .toString());
- }
-
- /**
- * @tests java.security.InvalidAlgorithmParameterException#InvalidAlgorithmParameterException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verifies constructor with one string parameter",
- method = "InvalidAlgorithmParameterException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.security.InvalidAlgorithmParameterException(java.lang.String)
- InvalidAlgorithmParameterException e = new InvalidAlgorithmParameterException(
- "test message");
- assertNotNull("Constructor returned null instance", e);
- assertEquals(
- "Failed toString test for constructed instance",
- "java.security.InvalidAlgorithmParameterException: test message",
- e.toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidKeyException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidKeyException2Test.java
deleted file mode 100644
index bbe9e08..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidKeyException2Test.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.InvalidKeyException;
-
-@TestTargetClass(InvalidKeyException.class)
-public class InvalidKeyException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.InvalidKeyException#InvalidKeyException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "InvalidKeyException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.InvalidKeyException()
- InvalidKeyException e = new InvalidKeyException();
- assertNotNull("Constructor returned a null", e);
- assertEquals("Failed toString test for constructed instance", "java.security.InvalidKeyException", e
- .toString());
- }
-
- /**
- * @tests java.security.InvalidKeyException#InvalidKeyException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verifies constructor with one string parameter",
- method = "InvalidKeyException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.security.InvalidKeyException(java.lang.String)
- InvalidKeyException e = new InvalidKeyException("test message");
- assertNotNull("Constructor returned a null", e);
- assertEquals("Failed toString test for constructed instance",
- "java.security.InvalidKeyException: test message", e
- .toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidParameterException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidParameterException2Test.java
deleted file mode 100644
index 4830731..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidParameterException2Test.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.InvalidParameterException;
-
-@TestTargetClass(InvalidParameterException.class)
-public class InvalidParameterException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.InvalidParameterException#InvalidParameterException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "InvalidParameterException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.InvalidParameterException()
- InvalidParameterException e = new InvalidParameterException();
- assertEquals("Failed toString test for constructed instance", "java.security.InvalidParameterException", e
- .toString());
- }
-
- /**
- * @tests java.security.InvalidParameterException#InvalidParameterException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verifies constructor with one variant of string parameter",
- method = "InvalidParameterException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.security.InvalidParameterException(java.lang.String)
- InvalidParameterException e = new InvalidParameterException(
- "test message");
- assertEquals("Failed toString test for constructed instance",
-
- "java.security.InvalidParameterException: test message", e
- .toString()
- );
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyException2Test.java
deleted file mode 100644
index 1c7b71f..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyException2Test.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.KeyException;
-
-@TestTargetClass(KeyException.class)
-public class KeyException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.KeyException#KeyException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "KeyException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.KeyException()
- KeyException e = new KeyException();
- assertEquals("Failed toString test for constructed instance", "java.security.KeyException", e
- .toString());
- }
-
- /**
- * @tests java.security.KeyException#KeyException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verifies constructor with one variant of string parameter",
- method = "KeyException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.security.KeyException(java.lang.String)
- KeyException e = new KeyException("test message");
- assertEquals("Failed toString test for constructed instance", "java.security.KeyException: test message", e
- .toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyManagementException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyManagementException2Test.java
deleted file mode 100644
index c30370a..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyManagementException2Test.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.KeyManagementException;
-
-@TestTargetClass(KeyManagementException.class)
-public class KeyManagementException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.KeyManagementException#KeyManagementException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "KeyManagementException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.KeyManagementException()
- KeyManagementException e = new KeyManagementException();
- assertEquals("Failed toString test for constructed instance",
- "java.security.KeyManagementException", e.toString());
- }
-
- /**
- * @tests java.security.KeyManagementException#KeyManagementException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Checking with null and empty string parameter missed",
- method = "KeyManagementException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.security.KeyManagementException(java.lang.String)
- KeyManagementException e = new KeyManagementException("test message");
- assertEquals("Failed toString test for constructed instance",
- "java.security.KeyManagementException: test message",
- e.toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java
index 817de35..059cef4 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java
@@ -1372,4 +1372,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreException2Test.java
deleted file mode 100644
index b3c9583..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreException2Test.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.KeyStoreException;
-
-@TestTargetClass(KeyStoreException.class)
-public class KeyStoreException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.KeyStoreException#KeyStoreException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "KeyStoreException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.KeyStoreException()
- KeyStoreException e = new KeyStoreException();
- assertEquals("Failed toString test for constructed instance", "java.security.KeyStoreException", e
- .toString());
- }
-
- /**
- * @tests java.security.KeyStoreException#KeyStoreException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verifies constructor with one variant of string parameter",
- method = "KeyStoreException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.security.KeyStoreException(java.lang.String)
- KeyStoreException e = new KeyStoreException("test message");
- assertEquals("Failed toString test for constructed instance",
- "java.security.KeyStoreException: test message", e
- .toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStorePrivateKeyEntryTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStorePrivateKeyEntryTest.java
new file mode 100644
index 0000000..42feeec
--- /dev/null
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStorePrivateKeyEntryTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.security.tests.java.security;
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import junit.framework.TestCase;
+
+public class KeyStorePrivateKeyEntryTest extends TestCase {
+
+ public void testGetCertificateChain() throws Exception {
+
+ String certificateData = "-----BEGIN CERTIFICATE-----\n"
+ + "MIICZTCCAdICBQL3AAC2MA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMSAw\n"
+ + "HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJl\n"
+ + "IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NzAyMjAwMDAwMDBa\n"
+ + "Fw05ODAyMjAyMzU5NTlaMIGWMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZv\n"
+ + "cm5pYTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQKExZTdW4gTWljcm9zeXN0\n"
+ + "ZW1zLCBJbmMuMSEwHwYDVQQLExhUZXN0IGFuZCBFdmFsdWF0aW9uIE9ubHkxGjAY\n"
+ + "BgNVBAMTEWFyZ29uLmVuZy5zdW4uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\n"
+ + "iQKBgQCofmdY+PiUWN01FOzEewf+GaG+lFf132UpzATmYJkA4AEA/juW7jSi+LJk\n"
+ + "wJKi5GO4RyZoyimAL/5yIWDV6l1KlvxyKslr0REhMBaD/3Z3EsLTTEf5gVrQS6sT\n"
+ + "WMoSZAyzB39kFfsB6oUXNtV8+UKKxSxKbxvhQn267PeCz5VX2QIDAQABMA0GCSqG\n"
+ + "SIb3DQEBAgUAA34AXl3at6luiV/7I9MN5CXYoPJYI8Bcdc1hBagJvTMcmlqL2uOZ\n"
+ + "H9T5hNMEL9Tk6aI7yZPXcw/xI2K6pOR/FrMp0UwJmdxX7ljV6ZtUZf7pY492UqwC\n"
+ + "1777XQ9UEZyrKJvF5ntleeO0ayBqLGVKCWzWZX9YsXCpv47FNLZbupE=\n"
+ + "-----END CERTIFICATE-----\n";
+
+ ByteArrayInputStream certArray;
+ {
+ try{
+ certArray = new ByteArrayInputStream(
+ certificateData.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ Certificate certificate = cf.generateCertificate(certArray);
+ assertTrue(certificate instanceof X509Certificate);
+
+ String algorithm = certificate.getPublicKey().getAlgorithm();
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator
+ .getInstance(algorithm);
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ PrivateKey privateKey = keyPair.getPrivate();
+
+ // If all the certificate in the chain is X509Certificate,
+ // KeyStore.PrivateKeyEntry will return a X509Certificate array.
+ KeyStore.PrivateKeyEntry privateKeyEntry = new KeyStore.PrivateKeyEntry(
+ privateKey, new Certificate[] { certificate });
+ Certificate[] chain = privateKeyEntry.getCertificateChain();
+ assertTrue(chain instanceof X509Certificate[]);
+
+ }
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
index d7ae43f..210116e 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
@@ -47,6 +47,8 @@
import java.util.Date;
import java.util.Set;
import java.math.BigInteger;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
import org.apache.harmony.security.tests.support.KeyStoreTestSupport;
import org.apache.harmony.security.tests.support.MyLoadStoreParams;
@@ -277,6 +279,35 @@
}
+
+ /*
+ * @tests java.security.KeyStoreSpi.engineEntryInstanceOf(String, Class<? extends Entry>)
+ */
+ public void testEngineEntryInstanceOf() throws Exception {
+ //Regression for HARMONY-615
+
+ // create a KeyStore
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(null, "pwd".toCharArray());
+
+ // generate a key
+ KeyGenerator keyGen = KeyGenerator.getInstance("DES");
+ keyGen.init(56);
+ SecretKey secretKey = keyGen.generateKey();
+
+ // put the key into keystore
+ String alias = "alias";
+ keyStore.setKeyEntry(alias, secretKey, "pwd".toCharArray(), null);
+
+ // check if it is a secret key
+ assertTrue(keyStore.entryInstanceOf(alias,
+ KeyStore.SecretKeyEntry.class));
+
+ // check if it is NOT a private key
+ assertFalse(keyStore.entryInstanceOf(alias,
+ KeyStore.PrivateKeyEntry.class));
+ }
+
/**
* @tests java.security.KeyStore.TrustedCertificateEntry.toString()
*/
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java
index c26708d..9eca936 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java
@@ -25,6 +25,7 @@
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -676,4 +677,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigestSpiTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigestSpiTest.java
index b7c11e5..8bcb392 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigestSpiTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigestSpiTest.java
@@ -109,29 +109,29 @@
)
public void test_engineDigestLB$LILI() throws Exception {
- final int DIGEST_LENGHT = 2;
+ final int DIGEST_LENGTH = 2;
MyMessageDigest md = new MyMessageDigest() {
public int engineGetDigestLength() {
- return DIGEST_LENGHT;
+ return DIGEST_LENGTH;
}
public byte[] engineDigest() {
- return new byte[DIGEST_LENGHT]; // return non-null value
+ return new byte[DIGEST_LENGTH]; // return non-null value
}
};
byte[] b = new byte[5];
try {
// test: null output buffer
- md.engineDigest(null, 1, DIGEST_LENGHT);
+ md.engineDigest(null, 1, DIGEST_LENGTH);
fail("No expected NullPointerException");
} catch (NullPointerException e) {
}
try {
//test: len param < digest length
- md.engineDigest(b, 1, DIGEST_LENGHT - 1);
+ md.engineDigest(b, 1, DIGEST_LENGTH - 1);
fail("No expected DigestException");
} catch (DigestException e) {
}
@@ -153,7 +153,7 @@
// ok
}
- assertEquals("incorrect result", DIGEST_LENGHT, md
+ assertEquals("incorrect result", DIGEST_LENGTH, md
.engineDigest(b, 1, 3));
// Regression for HARMONY-3045
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchAlgorithmException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchAlgorithmException2Test.java
deleted file mode 100644
index 289047b..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchAlgorithmException2Test.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.NoSuchAlgorithmException;
-
-@TestTargetClass(NoSuchAlgorithmException.class)
-public class NoSuchAlgorithmException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.NoSuchAlgorithmException#NoSuchAlgorithmException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "NoSuchAlgorithmException",
- args = {}
- )
- public void test_Constructor() {
- try {
- throw new NoSuchAlgorithmException();
- } catch (NoSuchAlgorithmException e) {
- assertNull("Message should be null", e.getMessage());
- assertEquals("Unexpected toString value",
- "java.security.NoSuchAlgorithmException", e.toString());
- }
- }
-
- /**
- * @tests java.security.NoSuchAlgorithmException#NoSuchAlgorithmException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Null parameter checking missed",
- method = "NoSuchAlgorithmException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.security.NoSuchAlgorithmException(java.lang.String)
- try {
- throw new NoSuchAlgorithmException("Test string");
- } catch (NoSuchAlgorithmException e) {
- assertEquals("Wrong message", "Test string", e.getMessage());
- assertEquals("Unexpected toString value",
- "java.security.NoSuchAlgorithmException: Test string", e
- .toString());
- }
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchProviderException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchProviderException2Test.java
deleted file mode 100644
index 256ed66..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchProviderException2Test.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.NoSuchProviderException;
-
-@TestTargetClass(NoSuchProviderException.class)
-public class NoSuchProviderException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.NoSuchProviderException#NoSuchProviderException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "NoSuchProviderException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.NoSuchProviderException()
- try {
- throw new NoSuchProviderException();
- } catch (NoSuchProviderException e) {
- assertNull("Message should be null", e.getMessage());
- assertEquals("Unexpected toString value",
- "java.security.NoSuchProviderException", e.toString());
- }
- }
-
- /**
- * @tests java.security.NoSuchProviderException#NoSuchProviderException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Null parameter checking missed",
- method = "NoSuchProviderException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.security.NoSuchProviderException(java.lang.String)
- try {
- throw new NoSuchProviderException("Test string");
- } catch (NoSuchProviderException e) {
- assertEquals("Wrong message", "Test string", e.getMessage());
- assertEquals("Unexpected toString value",
- "java.security.NoSuchProviderException: Test string", e
- .toString());
- }
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/Permissions2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/Permissions2Test.java
index af33804..a60adbf 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/Permissions2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/Permissions2Test.java
@@ -55,7 +55,7 @@
public void test_Constructor() {
// Test for method java.security.Permissions()
new Permissions();
- }
+ }
/**
* @tests java.security.Permissions#add(java.security.Permission)
@@ -192,4 +192,4 @@
public void checkPermission(Permission permission) {
}
}
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java
index 78038b5..ce57328 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java
@@ -31,6 +31,7 @@
import org.apache.harmony.security.tests.support.SecurityChecker;
import org.apache.harmony.security.tests.support.TestUtils;
+import tests.util.TestEnvironment;
import java.io.File;
import java.io.FilePermission;
@@ -60,6 +61,11 @@
junit.textui.TestRunner.run(PolicyTest.class);
}
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
/**
* @tests constructor Policy()
*/
@@ -395,7 +401,7 @@
String policyFile = getClass().getClassLoader().getResource(
"PolicyTest.txt").toString();
- String oldSysProp = System.getProperty(JAVA_SECURITY_POLICY);
+ String oldJavaPolicy = System.getProperty(JAVA_SECURITY_POLICY);
Policy oldPolicy = Policy.getPolicy();
try {
@@ -404,12 +410,20 @@
// test: absolute paths
assertCodeBasePropertyExpansion("/11111/*", "/11111/-");
assertCodeBasePropertyExpansion("/22222/../22222/*", "/22222/-");
+ assertCodeBasePropertyExpansion("/33333/*", "/33333/../33333/-");
+ assertCodeBasePropertyExpansion("/44444/../44444/-", "/44444/*");
+ assertCodeBasePropertyExpansion("/55555/../55555/-", "/55555/../55555/-");
+ assertCodeBasePropertyExpansion("/666 66 66/-", "/666 66 66/-");
// test: relative paths
- assertCodeBasePropertyExpansion("44444/*", "44444/-");
- assertCodeBasePropertyExpansion("55555/../55555/*", "55555/-");
+ assertCodeBasePropertyExpansion("11111/*", "11111/-");
+ assertCodeBasePropertyExpansion("22222/../22222/*", "22222/-");
+ assertCodeBasePropertyExpansion("33333/*", "33333/../33333/-");
+ assertCodeBasePropertyExpansion("44444/../44444/-", "44444/*");
+ assertCodeBasePropertyExpansion("55555/../55555/-", "55555/../55555/-");
+ assertCodeBasePropertyExpansion("666 66 66/-", "666 66 66/-");
} finally {
- TestUtils.setSystemProperty(JAVA_SECURITY_POLICY, oldSysProp);
+ TestUtils.setSystemProperty(JAVA_SECURITY_POLICY, oldJavaPolicy);
Policy.setPolicy(oldPolicy);
}
}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/Provider2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/Provider2Test.java
index 48e8f32..a8ec69a 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/Provider2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/Provider2Test.java
@@ -22,7 +22,10 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+import java.security.Security;
@TestTargetClass(Provider.class)
public class Provider2Test extends junit.framework.TestCase {
@@ -172,4 +175,44 @@
// Regression for HARMONY-3734
assertEquals("provTest version 1.2", provTest.toString());
}
+
+ // Regression Test for Provider.Service.getAlias(), which is an package
+ // private method but will lead to NPE thrown at
+ // Secure.SecurityDorr.getAliases
+ public void test_getAlias() throws Exception {
+ MockProvider mockProvider = new MockProvider("MOCKNAME", 1.0,
+ "MOCKINFO");
+ Provider.Service service = new Provider.Service(mockProvider,
+ "MOCKTYPE", "MOCKALGORITHM", "TESTCLASSNAME", null, null);
+ mockProvider.putService(service);
+ Security.addProvider(mockProvider);
+ try {
+ MessageDigest messageDigest = MessageDigest
+ .getInstance("NOTEXISTS");
+ }
+
+ catch (NoSuchAlgorithmException e) {
+ // expected
+ } finally {
+ Security.removeProvider("MOCKNAME");
+ }
+ }
+
+ public static class MockProvider extends Provider {
+
+ private static final long serialVersionUID = 1L;
+
+ public MockProvider(String name, double version, String info) {
+ super(name, version, info);
+
+ }
+
+ public void putService(Provider.Service service) {
+ super.putService(service);
+ }
+
+ public void removeService(Provider.Service service) {
+ super.removeService(service);
+ }
+ }
}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderException2Test.java
deleted file mode 100644
index 4b0f2ec..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderException2Test.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
-import java.security.ProviderException;
-
-@TestTargetClass(ProviderException.class)
-public class ProviderException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.ProviderException#ProviderException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "ProviderException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.ProviderException()
- ProviderException e = new ProviderException();
- assertEquals("Failed toString test for constructed instance",
- "java.security.ProviderException", e.toString());
- }
-
- /**
- * @tests java.security.ProviderException#ProviderException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verification with null/empty parameter is absent",
- method = "ProviderException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.security.ProviderException(java.lang.String)
- ProviderException e = new ProviderException("test message");
- assertEquals("Failed toString test for constructed instance",
- "java.security.ProviderException: test message", e
- .toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java
index c93011c..730e329 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderServiceTest.java
@@ -138,22 +138,16 @@
method = "newInstance",
args = {java.lang.Object.class}
)
- public void testNewInstance() {
+ public void testNewInstance() throws Exception {
Provider p = new MyProvider();
Provider.Service s = new Provider.Service(p, "SecureRandom",
- "algorithm", "org.apache.harmony.security.tests.support.RandomImpl", null,
- null);
- Object o = null;
- try {
- o = s.newInstance(null);
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- fail("newInstance() failed");
- }
- if (!(o instanceof RandomImpl)) {
- fail("incorrect instance");
- }
+ "algorithm",
+ "org.apache.harmony.security.tests.support.RandomImpl",
+ null, null);
+ Object o = s.newInstance(null);
+ assertTrue("incorrect instance", o instanceof RandomImpl);
+
try {
o = s.newInstance(new Object());
fail("No expected NoSuchAlgorithmException");
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
index a3b3077..3cc447f 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
@@ -129,27 +129,9 @@
)
public final void testClear() {
p.clear();
- if (p.getProperty("MessageDigest.ASH-1") != null) {
- fail("Provider contains properties");
- }
+ assertNull(p.getProperty("MessageDigest.SHA-1"));
}
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "clear",
- args = {}
- )
- public final void testClear_SecurityManager() {
- TestSecurityManager sm = new TestSecurityManager("clearProviderProperties.MyProvider");
- System.setSecurityManager(sm);
- p.clear();
- assertTrue("Provider.clear must call checkPermission with "
- + "SecurityPermission clearProviderProperties.NAME",
- sm.called);
- System.setSecurityManager(null);
- }
-
/*
* Class under test for void Provider(String, double, String)
*/
@@ -161,22 +143,13 @@
)
public final void testProviderStringdoubleString() {
Provider p = new MyProvider("Provider name", 123.456, "Provider info");
- if (!p.getName().equals("Provider name") || p.getVersion() != 123.456
- || !p.getInfo().equals("Provider info")) {
- fail("Incorrect values");
- }
+ assertEquals("Provider name", p.getName());
+ assertEquals(123.456, p.getVersion(), 0L);
+ assertEquals("Provider info", p.getInfo());
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getName",
- args = {}
- )
public final void testGetName() {
- if (!p.getName().equals("MyProvider")) {
- fail("Incorrect provider name");
- }
+ assertEquals("MyProvider", p.getName());
}
@TestTargetNew(
@@ -186,9 +159,7 @@
args = {}
)
public final void testGetVersion() {
- if (p.getVersion() != 1.0) {
- fail("Incorrect provider version");
- }
+ assertEquals(1.0, p.getVersion(), 0L);
}
@TestTargetNew(
@@ -198,9 +169,7 @@
args = {}
)
public final void testGetInfo() {
- if (!p.getInfo().equals("Provider for testing")) {
- fail("Incorrect provider info");
- }
+ assertEquals("Provider for testing", p.getInfo());
}
/*
@@ -213,19 +182,16 @@
args = {java.util.Map.class}
)
public final void testPutAllMap() {
- HashMap<String, String> hm = new HashMap<String, String>();
- hm.put("MessageDigest.ASH-1", "aaa.bbb.ccc.ddd");
+ HashMap hm = new HashMap();
+ hm.put("MessageDigest.SHA-1", "aaa.bbb.ccc.ddd");
hm.put("Property 1", "value 1");
hm.put("serviceName.algName attrName", "attrValue");
- hm.put("Alg.Alias.engineClassName.aliasName", "stanbdardName");
+ hm.put("Alg.Alias.engineClassName.aliasName", "standardName");
p.putAll(hm);
- if (!"value 1".equals(p.getProperty("Property 1").trim())
- || !"attrValue".equals(p.getProperty(
- "serviceName.algName attrName").trim())
- || !"stanbdardName".equals(p.getProperty(
- "Alg.Alias.engineClassName.aliasName").trim())
- || !"aaa.bbb.ccc.ddd".equals(p.getProperty(
- "MessageDigest.ASH-1").trim())) {
+ if (!"value 1".equals(p.getProperty("Property 1").trim()) ||
+ !"attrValue".equals(p.getProperty("serviceName.algName attrName").trim()) ||
+ !"standardName".equals(p.getProperty("Alg.Alias.engineClassName.aliasName").trim()) ||
+ !"aaa.bbb.ccc.ddd".equals(p.getProperty("MessageDigest.SHA-1").trim()) ) {
fail("Incorrect property value");
}
}
@@ -240,48 +206,43 @@
args = {}
)
public final void testEntrySet() {
- p.put("MessageDigest.ASH-256", "aaa.bbb.ccc.ddd");
-
- Set<Map.Entry<Object, Object>> s = p.entrySet();
+ p.put("MessageDigest.SHA-256", "aaa.bbb.ccc.ddd");
+
+ Set s = p.entrySet();
try {
s.clear();
fail("Must return unmodifiable set");
} catch (UnsupportedOperationException e) {
}
-
+
assertEquals("Incorrect set size", 8, s.size());
-
- for (Iterator<Entry<Object, Object>> it = s.iterator(); it.hasNext();) {
- Entry<Object, Object> e = it.next();
- String key = (String) e.getKey();
- String val = (String) e.getValue();
- if (key.equals("MessageDigest.ASH-1")
- && val.equals("SomeClassName")) {
+
+ for (Iterator it = s.iterator(); it.hasNext();) {
+ Entry e = (Entry)it.next();
+ String key = (String)e.getKey();
+ String val = (String)e.getValue();
+ if (key.equals("MessageDigest.SHA-1") && val.equals("SomeClassName")) {
continue;
}
- if (key.equals("Alg.Alias.MessageDigest.ASH1")
- && val.equals("ASH-1")) {
+ if (key.equals("Alg.Alias.MessageDigest.SHA1") && val.equals("SHA-1")) {
continue;
}
if (key.equals("MessageDigest.abc") && val.equals("SomeClassName")) {
continue;
}
- if (key.equals("Provider.id className")
- && val.equals(p.getClass().getName())) {
+ if (key.equals("Provider.id className") && val.equals(p.getClass().getName())) {
continue;
}
if (key.equals("Provider.id name") && val.equals("MyProvider")) {
continue;
}
- if (key.equals("MessageDigest.ASH-256")
- && val.equals("aaa.bbb.ccc.ddd")) {
+ if (key.equals("MessageDigest.SHA-256") && val.equals("aaa.bbb.ccc.ddd")) {
continue;
}
if (key.equals("Provider.id version") && val.equals("1.0")) {
continue;
}
- if (key.equals("Provider.id info")
- && val.equals("Provider for testing")) {
+ if (key.equals("Provider.id info") && val.equals("Provider for testing")) {
continue;
}
fail("Incorrect set");
@@ -298,30 +259,27 @@
args = {}
)
public final void testKeySet() {
- p.put("MessageDigest.ASH-256", "aaa.bbb.ccc.ddd");
+ p.put("MessageDigest.SHA-256", "aaa.bbb.ccc.ddd");
Set<Object> s = p.keySet();
try {
s.clear();
} catch (UnsupportedOperationException e) {
}
- Set<Object> s1 = p.keySet();
- if ((s == s1) || s1.isEmpty()) {
- fail("Must return unmodifiable set");
- }
- if (s1.size() != 8) {
- fail("Incorrect set size");
- }
- if (!s1.contains("MessageDigest.ASH-256")
- || !s1.contains("MessageDigest.ASH-1")
- || !s1.contains("Alg.Alias.MessageDigest.ASH1")
- || !s1.contains("MessageDigest.abc")
- || !s1.contains("Provider.id info")
- || !s1.contains("Provider.id className")
- || !s1.contains("Provider.id version")
- || !s1.contains("Provider.id name")) {
- fail("Incorrect set");
- }
+ Set s1 = p.keySet();
+
+ assertNotSame(s, s1);
+ assertFalse(s1.isEmpty());
+ assertEquals(8, s1.size());
+
+ assertTrue(s1.contains("MessageDigest.SHA-256"));
+ assertTrue(s1.contains("MessageDigest.SHA-1"));
+ assertTrue(s1.contains("Alg.Alias.MessageDigest.SHA1"));
+ assertTrue(s1.contains("MessageDigest.abc"));
+ assertTrue(s1.contains("Provider.id info"));
+ assertTrue(s1.contains("Provider.id className"));
+ assertTrue(s1.contains("Provider.id version"));
+ assertTrue(s1.contains("Provider.id name"));
}
/*
@@ -341,19 +299,19 @@
c.clear();
} catch (UnsupportedOperationException e) {
}
- Collection<Object> c1 = p.values();
- if ((c == c1) || c1.isEmpty()) {
- fail("Must return unmodifiable set");
- }
- if (c1.size() != 8) {
- fail("Incorrect set size " + c1.size());
- }
- if (!c1.contains("MyProvider") || !c1.contains("aaa.bbb.ccc.ddd")
- || !c1.contains("Provider for testing") || !c1.contains("1.0")
- || !c1.contains("SomeClassName") || !c1.contains("ASH-1")
- || !c1.contains(p.getClass().getName())) {
- fail("Incorrect set");
- }
+ Collection c1 = p.values();
+
+ assertNotSame(c, c1);
+ assertFalse(c1.isEmpty());
+ assertEquals(8, c1.size());
+
+ assertTrue(c1.contains("MyProvider"));
+ assertTrue(c1.contains("aaa.bbb.ccc.ddd"));
+ assertTrue(c1.contains("Provider for testing"));
+ assertTrue(c1.contains("1.0"));
+ assertTrue(c1.contains("SomeClassName"));
+ assertTrue(c1.contains("SHA-1"));
+ assertTrue(c1.contains(p.getClass().getName()));
}
/*
@@ -366,38 +324,124 @@
args = {java.lang.Object.class, java.lang.Object.class}
)
public final void testPutObjectObject() {
- p.put("MessageDigest.ASH-1", "aaa.bbb.ccc.ddd");
+ p.put("MessageDigest.SHA-1", "aaa.bbb.ccc.ddd");
p.put("Type.Algorithm", "className");
- if (!"aaa.bbb.ccc.ddd".equals(p.getProperty("MessageDigest.ASH-1")
- .trim())) {
- fail("Incorrect property value");
- }
-
- Set<Service> services = p.getServices();
- if (services.size() != 3) {
- fail("incorrect size");
- }
- for (Iterator<Service> it = services.iterator(); it.hasNext();) {
- Provider.Service s = it.next();
- if ("Type".equals(s.getType())
- && "Algorithm".equals(s.getAlgorithm())
- && "className".equals(s.getClassName())) {
+ assertEquals("aaa.bbb.ccc.ddd", p.getProperty("MessageDigest.SHA-1")
+ .trim());
+
+ Set services = p.getServices();
+ assertEquals(3, services.size());
+
+ for (Iterator it = services.iterator(); it.hasNext();) {
+ Provider.Service s = (Provider.Service)it.next();
+ if ("Type".equals(s.getType()) &&
+ "Algorithm".equals(s.getAlgorithm()) &&
+ "className".equals(s.getClassName())) {
continue;
}
- if ("MessageDigest".equals(s.getType())
- && "ASH-1".equals(s.getAlgorithm())
- && "aaa.bbb.ccc.ddd".equals(s.getClassName())) {
+ if ("MessageDigest".equals(s.getType()) &&
+ "SHA-1".equals(s.getAlgorithm()) &&
+ "aaa.bbb.ccc.ddd".equals(s.getClassName())) {
continue;
}
- if ("MessageDigest".equals(s.getType())
- && "abc".equals(s.getAlgorithm())
- && "SomeClassName".equals(s.getClassName())) {
+ if ("MessageDigest".equals(s.getType()) &&
+ "abc".equals(s.getAlgorithm()) &&
+ "SomeClassName".equals(s.getClassName())) {
continue;
}
fail("Incorrect service");
}
}
+ /*
+ * Class under test for Object remove(Object)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "remove",
+ args = {java.lang.Object.class}
+ )
+ public final void testRemoveObject() {
+ Object o = p.remove("MessageDigest.SHA-1");
+
+ assertEquals("SomeClassName", o);
+ assertNull(p.getProperty("MessageDigest.SHA-1"));
+ assertEquals(1, p.getServices().size());
+ }
+
+ public final void testService1() {
+ p.put("MessageDigest.SHA-1", "AnotherClassName");
+ Provider.Service s = p.getService("MessageDigest", "SHA-1");
+
+ assertEquals("AnotherClassName", s.getClassName());
+ }
+
+ // Regression for HARMONY-2760.
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Regression test: verifies constructor with two null parameters.",
+ method = "Provider",
+ args = {java.lang.String.class, double.class, java.lang.String.class}
+ )
+ public void testConstructor() {
+ MyProvider myProvider = new MyProvider(null, 1, null);
+ assertNull(myProvider.getName());
+ assertNull(myProvider.getInfo());
+ assertEquals("null", myProvider.getProperty("Provider.id name"));
+ assertEquals("null", myProvider.getProperty("Provider.id info"));
+ }
+
+ class MyProvider extends Provider {
+ MyProvider() {
+ super("MyProvider", 1.0, "Provider for testing");
+ put("MessageDigest.SHA-1", "SomeClassName");
+ put("MessageDigest.abc", "SomeClassName");
+ put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
+ }
+
+ MyProvider(String name, double version, String info) {
+ super(name, version, info);
+ }
+
+ // BEGIN android-added
+ public void putService(Provider.Service s) {
+ super.putService(s);
+ }
+ // END android-added
+
+ // BEGIN android-added
+ public void removeService(Provider.Service s) {
+ super.removeService(s);
+ }
+ // END android-added
+
+ // BEGIN android-added
+ public int getNumServices() {
+ return getServices().size();
+ }
+ // END android-added
+ }
+
+ // BEGIN android-added
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "clear",
+ args = {}
+ )
+ public final void testClear_SecurityManager() {
+ TestSecurityManager sm = new TestSecurityManager("clearProviderProperties.MyProvider");
+ System.setSecurityManager(sm);
+ p.clear();
+ assertTrue("Provider.clear must call checkPermission with "
+ + "SecurityPermission clearProviderProperties.NAME",
+ sm.called);
+ System.setSecurityManager(null);
+ }
+ // END android-added
+
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
@@ -414,39 +458,9 @@
+ "SecurityPermission putProviderProperty.Name", sm.called);
System.setSecurityManager(null);
}
+ // END android-added
- /*
- * Class under test for Object remove(Object)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "remove",
- args = {java.lang.Object.class}
- )
- public final void testRemoveObject() {
- Object o = p.remove("MessageDigest.ASH-1");
- if (!"SomeClassName".equals(o)) {
- fail("Incorrect return value");
- }
- if (p.getProperty("MessageDigest.ASH-1") != null) {
- fail("Provider contains properties");
- }
- if (p.getServices().size() != 1) {
- fail("Service not removed");
- }
-
- try {
- p.remove(null);
- fail("expected NullPointerException");
- } catch (NullPointerException e) {
- // ok
- }
- }
-
- /*
- * Class under test for Object remove(Object)
- */
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
@@ -463,35 +477,9 @@
sm.called);
System.setSecurityManager(null);
}
+ // END android-added
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getService",
- args = {java.lang.String.class, java.lang.String.class}
- )
- public final void testService1() {
- p.put("MessageDigest.ASH-1", "AnotherClassName");
- Provider.Service s = p.getService("MessageDigest", "ASH-1");
- if (!"AnotherClassName".equals(s.getClassName())) {
- fail("Incorrect class name " + s.getClassName());
- }
-
- try {
- p.getService("MessageDigest", null);
- fail("expected NullPointerException");
- } catch (NullPointerException e) {
- // ok;
- }
-
- try {
- p.getService(null, "ASH-1");
- fail("expected NullPointerException");
- } catch (NullPointerException e) {
- // ok
- }
- }
-
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -516,23 +504,9 @@
} catch (NoSuchAlgorithmException e) {
}
}
-
+ // END android-added
- // Regression for HARMONY-2760.
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Regression test: verifies constructor with two null parameters.",
- method = "Provider",
- args = {java.lang.String.class, double.class, java.lang.String.class}
- )
- public void testConstructor() {
- MyProvider myProvider = new MyProvider(null, 1, null);
- assertNull(myProvider.getName());
- assertNull(myProvider.getInfo());
- assertEquals("null", myProvider.getProperty("Provider.id name"));
- assertEquals("null", myProvider.getProperty("Provider.id info"));
- }
-
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -576,7 +550,9 @@
assertTrue(!actual.contains(s[1]));
assertTrue(actual.contains(s[2]));
}
+ // END android-added
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -631,7 +607,9 @@
// expected
}
}
+ // END android-added
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -703,10 +681,9 @@
// expected
}
}
+ // END android-added
- /*
- * Class under test for void load(InputStream)
- */
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
@@ -735,7 +712,9 @@
// expected
}
}
-
+ // END android-added
+
+ // BEGIN android-added
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
@@ -755,11 +734,12 @@
p.load(new TestInputStream());
fail("expected IOException");
} catch (IOException e) {
- // ok
+ // expected
}
-
}
+ // END android-added
+ // BEGIN android-added
protected byte[] writeProperties() {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(bout);
@@ -769,34 +749,9 @@
ps.close();
return bout.toByteArray();
}
+ // END android-added
- class MyProvider extends Provider {
- // private Set<Provider.Service> services = null;
-
- MyProvider() {
- super("MyProvider", 1.0, "Provider for testing");
- put("MessageDigest.ASH-1", "SomeClassName");
- put("MessageDigest.abc", "SomeClassName");
- put("Alg.Alias.MessageDigest.ASH1", "ASH-1");
- }
-
- MyProvider(String name, double version, String info) {
- super(name, version, info);
- }
-
- public void putService(Provider.Service s) {
- super.putService(s);
- }
-
- public void removeService(Provider.Service s) {
- super.removeService(s);
- }
-
- public int getNumServices() {
- return getServices().size();
- }
- }
-
+ // BEGIN android-added
static class TestSecurityManager extends SecurityManager {
boolean called = false;
private final String permissionName;
@@ -814,4 +769,5 @@
}
}
}
+ // END android-added
}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java
index 49a0365..a59ada5 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/Security2Test.java
@@ -358,4 +358,4 @@
Security.removeProvider(entrust.getName());
}
}
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java
index c03afc5..aa4c71b 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java
@@ -205,9 +205,7 @@
}
assertEquals("Providers not removed", 0,
Security.getProviders().length);
- } catch (Exception e) {
- e.printStackTrace();
- } finally { // restore providers
+ } finally { // restore providers
for (int i = 0; i < providers.length; i++) {
Security.addProvider(providers[i]);
}
@@ -453,6 +451,9 @@
fail("No expected NullPointerException.");
} catch (NullPointerException e) {
}
+
+ Security.setProperty("myprop","test white space ");
+ assertEquals("test white space", Security.getProperty("myprop"));
}
/**
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
index 20bc4b1..a657f60 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/Signature2Test.java
@@ -39,6 +39,7 @@
import java.security.cert.Certificate;
import java.security.spec.DSAParameterSpec;
import java.util.HashSet;
+import java.util.Locale;
import java.util.Set;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureException2Test.java
deleted file mode 100644
index 9a6209a..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureException2Test.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-
-import java.security.SignatureException;
-
-@TestTargetClass(SignatureException.class)
-public class SignatureException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.SignatureException#SignatureException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "SignatureException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.SignatureException()
- SignatureException e = new SignatureException();
- assertEquals("Failed toString test for constructed instance", "java.security.SignatureException", e
- .toString());
- }
-
- /**
- * @tests java.security.SignatureException#SignatureException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verification with null string parameter missed",
- method = "SignatureException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method java.security.SignatureException(java.lang.String)
- SignatureException e = new SignatureException("test message");
- assertEquals("Failed toString test for constructed instance",
- "java.security.SignatureException: test message", e
- .toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/SignedObjectTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/SignedObjectTest.java
index 77f341b..89d872e 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/SignedObjectTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/SignedObjectTest.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-/**
-* @author Boris V. Kuznetsov
-* @version $Revision$
-*/
-
package org.apache.harmony.security.tests.java.security;
import dalvik.annotation.TestLevel;
@@ -27,6 +22,11 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import java.security.NoSuchAlgorithmException;
+import java.security.Signature;
+import java.security.SignedObject;
+import java.util.Properties;
+
import junit.framework.TestCase;
import org.apache.harmony.security.tests.support.TestKeyPair;
@@ -47,7 +47,6 @@
@TestTargetClass(SignedObject.class)
/**
* Tests for <code>SignedObject</code> constructor and methods
- *
*/
public class SignedObjectTest extends TestCase {
@@ -83,17 +82,11 @@
args = {java.security.PublicKey.class, java.security.Signature.class}
)
})
- public void testSignedObject() {
- Signature sig = null;
+ public void testSignedObject() throws Exception {
TestKeyPair tkp = null;
Properties prop;
-
- try {
- sig = Signature.getInstance("SHA1withDSA");
- } catch (NoSuchAlgorithmException e) {
- fail(e.toString());
- }
-
+ Signature sig = Signature.getInstance("SHA1withDSA");
+
try {
tkp = new TestKeyPair("DSA");
} catch (NoSuchAlgorithmException e) {
@@ -102,133 +95,14 @@
}
prop = new Properties();
prop.put("aaa", "bbb");
- SignedObject so = null;
- try {
- so = new SignedObject(prop, tkp.getPrivate(), sig);
- } catch (IOException e) {
- fail(e.toString());
- } catch (SignatureException e) {
- fail(e.toString());
- } catch (InvalidKeyException e) {
- fail(e.toString());
- } catch (InvalidKeySpecException e) {
- fail(e.toString());
- }
+
+ SignedObject so = new SignedObject(prop, tkp.getPrivate(), sig);
assertEquals("SHA1withDSA", so.getAlgorithm());
-
- try {
- assertEquals(so.getObject(), prop);
- } catch (ClassNotFoundException e) {
- fail(e.toString());
- } catch (IOException e) {
- fail(e.toString());
- }
- try {
- if (!so.verify(tkp.getPublic(), sig)) {
- fail("verify() failed");
- }
- } catch (SignatureException e) {
- fail(e.toString());
- } catch (InvalidKeyException e) {
- fail(e.toString());
- } catch (InvalidKeySpecException e) {
- fail(e.toString());
- }
-
- if (so.getSignature() == null) {
- fail("signature is null");
- }
-
- try {
- TestKeyPair tkp2 = new TestKeyPair("DH");
- so = new SignedObject(prop, tkp2.getPrivate(), sig);
- } catch(InvalidKeyException e) {
- // ok
- } catch (NoSuchAlgorithmException e) {
- fail(e.toString());
- } catch (SignatureException e) {
- fail(e.toString());
- } catch (InvalidKeySpecException e) {
- fail(e.toString());
- } catch (IOException e) {
- fail(e.toString());
- }
-
- try {
- new SignedObject(new Serializable() {
- private void writeObject(ObjectOutputStream out) throws IOException {
- throw new IOException();
- }
- }, tkp.getPrivate(), sig);
- } catch(InvalidKeyException e) {
- fail(e.toString());
- } catch (SignatureException e) {
- fail(e.toString());
- } catch (InvalidKeySpecException e) {
- fail(e.toString());
- } catch (IOException e) {
- // ok
- }
+ assertEquals(prop, so.getObject());
-
- try {
- new SignedObject(prop, tkp.getPrivate(), new Signature("TST") {
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- throw new SignatureException();
- }
-
- @Override
- protected void engineUpdate(byte[] b, int off, int len)
- throws SignatureException {
- throw new SignatureException();
- }
-
- @Override
- protected void engineUpdate(byte b) throws SignatureException {
- throw new SignatureException();
- }
-
- @Override
- protected byte[] engineSign() throws SignatureException {
- throw new SignatureException();
- }
-
- @Override
- protected void engineSetParameter(String param, Object value)
- throws InvalidParameterException {
-
- }
-
- @Override
- protected void engineInitVerify(PublicKey publicKey)
- throws InvalidKeyException {
-
- }
-
- @Override
- protected void engineInitSign(PrivateKey privateKey)
- throws InvalidKeyException {
-
- }
-
- @Override
- protected Object engineGetParameter(String param)
- throws InvalidParameterException {
- return null;
- }
- });
- } catch(InvalidKeyException e) {
- fail(e.toString());
- } catch (SignatureException e) {
- // ok
- } catch (InvalidKeySpecException e) {
- fail(e.toString());
- } catch (IOException e) {
- fail(e.toString());
- }
-
+ assertTrue("verify() failed", so.verify(tkp.getPublic(), sig));
+
+ assertNotNull("signature is null", so.getSignature());
}
}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java
index c3414f4..1015521 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java
@@ -118,7 +118,7 @@
args = {}
)
public void testGetTimestamp() {
- Timestamp t = new Timestamp(now, cpath);
+ Timestamp t = new Timestamp(now, cpath);
assertEquals(now, t.getTimestamp());
assertNotSame(now, t.getTimestamp());
}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyException2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyException2Test.java
deleted file mode 100644
index ce97d60..0000000
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyException2Test.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.security.tests.java.security;
-
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-
-import java.security.UnrecoverableKeyException;
-
-@TestTargetClass(UnrecoverableKeyException.class)
-public class UnrecoverableKeyException2Test extends junit.framework.TestCase {
-
- /**
- * @tests java.security.UnrecoverableKeyException#UnrecoverableKeyException()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "UnrecoverableKeyException",
- args = {}
- )
- public void test_Constructor() {
- // Test for method java.security.UnrecoverableKeyException()
- UnrecoverableKeyException e = new UnrecoverableKeyException();
- assertEquals("Failed toString test for constructed instance", "java.security.UnrecoverableKeyException", e
- .toString());
- }
-
- /**
- * @tests java.security.UnrecoverableKeyException#UnrecoverableKeyException(java.lang.String)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "Verification with null string parameter missed",
- method = "UnrecoverableKeyException",
- args = {java.lang.String.class}
- )
- public void test_ConstructorLjava_lang_String() {
- // Test for method
- // java.security.UnrecoverableKeyException(java.lang.String)
- UnrecoverableKeyException e = new UnrecoverableKeyException(
- "test message");
- assertEquals("Failed toString test for constructed instance",
- "java.security.UnrecoverableKeyException: test message", e
- .toString());
- }
-}
\ No newline at end of file
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java
index ce02e9d..d03b43d 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java
@@ -42,6 +42,11 @@
import tests.util.SerializationTester;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
+
+import tests.util.SerializationTester;
+
import junit.framework.TestCase;
@TestTargetClass(UnresolvedPermission.class)
@@ -111,7 +116,6 @@
assertFalse(up.implies(new AllPermission()));
assertFalse(up.implies(new SecurityPermission("a.b.c")));
}
-
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -134,7 +138,6 @@
assertEquals("actions", deserializedUp.getUnresolvedActions());
assertNull(deserializedUp.getUnresolvedCerts());
}
-
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -155,14 +158,11 @@
assertEquals("java.security.SecurityPermission", deserializedUp
.getUnresolvedType());
assertEquals("a.b.c", deserializedUp.getUnresolvedName());
- assertEquals("action", deserializedUp.getUnresolvedActions());
- Certificate[] certs = deserializedUp.getUnresolvedCerts();
- assertNotNull(certs);
- assertEquals(1, certs.length);
+ assertEquals("actions", deserializedUp.getUnresolvedActions());
+ assertNull(deserializedUp.getUnresolvedCerts());
}
});
}
-
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
diff --git a/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java b/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java
index f36f119..267923a 100644
--- a/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java
+++ b/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java
@@ -28,6 +28,8 @@
import java.util.StringTokenizer;
import tests.support.Support_Exec;
+import static tests.support.Support_Exec.javaProcessBuilder;
+import static tests.support.Support_Exec.execAndGetOutput;
import tests.support.Support_GetLocal;
import tests.support.resource.Support_Resources;
import dalvik.annotation.KnownFailure;
@@ -168,17 +170,14 @@
}
}
- String classPath = new File(classURL.getFile()).getPath();
-
- // Execute Support_PermissionCollection in another VM
- String[] classPathArray = new String[2];
- classPathArray[0] = classPath;
- classPathArray[1] = jarFile.getPath();
- String[] args = { "-Djava.security.policy=" + policyFile.toURL(),
- "tests.support.Support_PermissionCollection",
- signedBKS.toExternalForm() };
-
- String result = Support_Exec.execJava(args, classPathArray, true);
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("-cp");
+ builder.command().add(Support_Exec.createPath(
+ new File(classURL.getFile()).getPath(), jarFile.getPath()));
+ builder.command().add("-Djava.security.policy=" + policyFile.toURL());
+ builder.command().add("tests.support.Support_PermissionCollection");
+ builder.command().add(signedBKS.toExternalForm());
+ String result = execAndGetOutput(builder);
StringTokenizer resultTokenizer = new StringTokenizer(result, ",");
@@ -266,6 +265,7 @@
"testing permissionCollection-isREadOnly");
assertNotNull("toString should have returned a string of elements",
permi.newPermissionCollection().toString());
+ assertTrue(permi.newPermissionCollection().toString().endsWith("\n"));
}
// FIXME move me to Support_Resources
diff --git a/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java b/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java
index d1bf7c2..b9217a1 100644
--- a/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java
+++ b/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java
@@ -22,6 +22,7 @@
import dalvik.annotation.TestTargetClass;
import junit.framework.TestCase;
+import tests.util.TestEnvironment;
import java.io.InputStream;
import java.io.PrintStream;
@@ -46,6 +47,7 @@
@Override
protected void tearDown() throws Exception {
+ TestEnvironment.reset();
System.setSecurityManager(old);
super.tearDown();
}
diff --git a/security/src/test/resources/serialization/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.golden.ser b/security/src/test/resources/serialization/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.golden.ser
index 2937f2f..931ee3f 100755
--- a/security/src/test/resources/serialization/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.golden.ser
+++ b/security/src/test/resources/serialization/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.golden.ser
Binary files differ
diff --git a/sql/src/main/native/sqlite_jni.c b/sql/src/main/native/sqlite_jni.c
index 4923869..341ef2e 100644
--- a/sql/src/main/native/sqlite_jni.c
+++ b/sql/src/main/native/sqlite_jni.c
@@ -1,3 +1,5 @@
+#include "JNIHelp.h"
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -276,23 +278,13 @@
static void
throwex(JNIEnv *env, const char *msg)
{
- jclass except = (*env)->FindClass(env, "SQLite/Exception");
-
- (*env)->ExceptionClear(env);
- if (except) {
- (*env)->ThrowNew(env, except, msg);
- }
+ jniThrowException(env, "SQLite/Exception", msg);
}
static void
throwoom(JNIEnv *env, const char *msg)
{
- jclass except = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
-
- (*env)->ExceptionClear(env);
- if (except) {
- (*env)->ThrowNew(env, except, msg);
- }
+ jniThrowException(env, "java/lang/OutOfMemoryError", msg);
}
static void
@@ -305,12 +297,7 @@
static void
throwioex(JNIEnv *env, const char *msg)
{
- jclass except = (*env)->FindClass(env, "java/io/IOException");
-
- (*env)->ExceptionClear(env);
- if (except) {
- (*env)->ThrowNew(env, except, msg);
- }
+ jniThrowException(env, "java/io/IOException", msg);
}
#endif
@@ -331,16 +318,14 @@
dest->result = 0;
dest->tofree = 0;
if (haveutf) {
- const char *utf = (*env)->GetStringUTFChars(env, src, 0);
-
- if (!utf) {
- return dest->result;
- }
- dest->tofree = malloc(strlen(utf) + 1);
- dest->result = dest->tofree;
- strcpy(dest->result, utf);
- (*env)->ReleaseStringUTFChars(env, src, utf);
- return dest->result;
+ const jsize utfLength = (*env)->GetStringUTFLength(env, src);
+ dest->result = dest->tofree = malloc(utfLength + 1);
+ if (!dest->tofree) {
+ throwoom(env, "string translation failed");
+ return dest->result;
+ }
+ (*env)->GetStringUTFRegion(env, src, 0, utfLength, dest->result);
+ return dest->result;
}
if (enc) {
bytes = (*env)->CallObjectMethod(env, src,
@@ -418,6 +403,7 @@
"(Ljava/lang/String;I)Z");
if (mid == 0) {
+ (*env)->DeleteLocalRef(env, cls);
return ret;
}
trans2utf(env, h->haveutf, h->enc, table, &tabstr);
@@ -425,6 +411,7 @@
(jint) count)
!= JNI_FALSE;
(*env)->DeleteLocalRef(env, tabstr.jstr);
+ (*env)->DeleteLocalRef(env, cls);
}
return ret;
}
@@ -444,10 +431,12 @@
"(Ljava/lang/String;I)Z");
if (mid == 0) {
+ (*env)->DeleteLocalRef(env, cls);
return ret;
}
ret = (*env)->CallBooleanMethod(env, h->bh, mid, 0, (jint) count)
!= JNI_FALSE;
+ (*env)->DeleteLocalRef(env, cls);
}
return ret;
}
@@ -465,9 +454,11 @@
jmethodID mid = (*env)->GetMethodID(env, cls, "progress", "()Z");
if (mid == 0) {
+ (*env)->DeleteLocalRef(env, cls);
return ret;
}
ret = (*env)->CallBooleanMethod(env, h->ph, mid) != JNI_TRUE;
+ (*env)->DeleteLocalRef(env, cls);
}
return ret;
}
@@ -1331,11 +1322,10 @@
}
if (h) {
if (h->sqlite) {
- jboolean b;
jthrowable exc;
int rc = SQLITE_ERROR, nargs, i;
char *err = 0, *p;
- const char *str = (*env)->GetStringUTFChars(env, sql, &b);
+ const char *str = (*env)->GetStringUTFChars(env, sql, NULL);
transstr sqlstr;
struct args {
char *arg;
@@ -1611,6 +1601,7 @@
int i;
if (mid == 0) {
+ (*env)->DeleteLocalRef(env, cls);
return;
}
arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
@@ -1659,6 +1650,7 @@
jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
"(LSQLite/FunctionContext;)V");
if (mid == 0) {
+ (*env)->DeleteLocalRef(env, cls);
return;
}
f->sf = sf;
@@ -1685,6 +1677,7 @@
int i;
if (mid == 0) {
+ (*env)->DeleteLocalRef(env, cls);
return;
}
arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
@@ -1734,6 +1727,7 @@
jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
"(LSQLite/FunctionContext;)V");
if (mid == 0) {
+ (*env)->DeleteLocalRef(env, cls);
return;
}
f->sf = sf;
@@ -3009,10 +3003,9 @@
hvm *v;
jvalue vv;
jthrowable exc;
- jboolean b;
int rc = SQLITE_ERROR, nargs, i;
char *p;
- const char *str = (*env)->GetStringUTFChars(env, sql, &b);
+ const char *str = (*env)->GetStringUTFChars(env, sql, NULL);
const char *tail;
transstr sqlstr;
struct args {
@@ -3401,7 +3394,7 @@
return;
}
len16 = len16 + sizeof (jchar) - ((char *) tail - (char *) sql16);
- if (len16 < sizeof (jchar)) {
+ if (len16 < (jsize) sizeof (jchar)) {
len16 = sizeof (jchar);
}
v = malloc(sizeof (hvm) + len16);
@@ -3674,19 +3667,16 @@
return;
}
if (val) {
- len = (*env)->GetStringLength(env, val);
+ const jsize charCount = (*env)->GetStringLength(env, val);
+ len = charCount * sizeof(jchar);
if (len > 0) {
- const jchar *ch;
-
- len *= sizeof (jchar);
data = sqlite3_malloc(len);
if (!data) {
throwoom(env, "unable to get blob parameter");
return;
}
- ch = (*env)->GetStringChars(env, val, 0);
- memcpy(data, ch, len);
- (*env)->ReleaseStringChars(env, val, ch);
+
+ (*env)->GetStringRegion(env, val, 0, charCount, (jchar*) data);
ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm,
pos, data, len, sqlite3_free);
} else {
diff --git a/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java b/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
index 68ac6c5..d53f078 100644
--- a/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
+++ b/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
@@ -19,12 +19,10 @@
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import java.io.ByteArrayOutputStream;
-import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.Method;
@@ -37,9 +35,12 @@
import java.sql.SQLPermission;
import java.util.Enumeration;
import java.util.Properties;
-import tests.support.Support_Exec;
import junit.framework.TestCase;
+import static tests.support.Support_Exec.javaProcessBuilder;
+import static tests.support.Support_Exec.execAndGetOutput;
+import tests.util.TestEnvironment;
+
@TestTargetClass(DriverManager.class)
/**
* JUnit Testcase for the java.sql.DriverManager class
@@ -77,6 +78,7 @@
// test methods as needed.
@Override
public void setUp() {
+ TestEnvironment.reset();
numberLoaded = loadDrivers();
} // end setUp()
@@ -715,10 +717,9 @@
* Regression for HARMONY-4303
*/
public void test_initClass() throws Exception {
- String[] arg = new String[1];
- arg[0] = "org/apache/harmony/sql/tests/java/sql/TestMainForDriver";
- String result = Support_Exec.execJava(arg, null, true);
- assertEquals("", result);
+ ProcessBuilder builder = javaProcessBuilder();
+ builder.command().add("org/apache/harmony/sql/tests/java/sql/TestMainForDriver");
+ assertEquals("", execAndGetOutput(builder));
}
private static class BadDummyDriver extends DummyDriver {
diff --git a/sql/src/test/java/tests/java/sql/StressTest.java b/sql/src/test/java/tests/java/sql/StressTest.java
index 555ad03..b6d13c1 100755
--- a/sql/src/test/java/tests/java/sql/StressTest.java
+++ b/sql/src/test/java/tests/java/sql/StressTest.java
@@ -16,8 +16,8 @@
package tests.java.sql;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -30,7 +30,6 @@
import java.sql.Statement;
import java.util.Properties;
import java.util.Vector;
-import java.util.logging.Level;
import java.util.logging.Logger;
import tests.support.DatabaseCreator;
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/cert/MyCertStoreParameters.java b/support/src/test/java/org/apache/harmony/security/tests/support/cert/MyCertStoreParameters.java
index 6518c6f..1166b41 100644
--- a/support/src/test/java/org/apache/harmony/security/tests/support/cert/MyCertStoreParameters.java
+++ b/support/src/test/java/org/apache/harmony/security/tests/support/cert/MyCertStoreParameters.java
@@ -37,7 +37,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
}
diff --git a/support/src/test/java/tests/support/Support_Exec.java b/support/src/test/java/tests/support/Support_Exec.java
index c3a5ccc..2e709a5 100644
--- a/support/src/test/java/tests/support/Support_Exec.java
+++ b/support/src/test/java/tests/support/Support_Exec.java
@@ -17,204 +17,136 @@
package tests.support;
-import java.io.ByteArrayOutputStream;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-
-import junit.framework.TestCase;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
public class Support_Exec extends TestCase {
- static final boolean againstDalvik;
- static {
- String platform = System.getProperty("java.vendor");
- againstDalvik = (platform.contains("Android"));
- }
+ private static final boolean againstDalvik
+ = System.getProperty("java.vendor").contains("Android");
/**
- * This function returns the output of the process as a string
+ * Returns a builder configured with the appropriate VM ("dalvikvm" or
+ * "java") and arguments (as specified by the system property
+ * {@code hy.test.vmargs}).
*/
- public static String execJava(String[] args, String[] classpath,
- boolean displayOutput) throws IOException, InterruptedException {
- Object[] arr =
- execJavaCommon(args, classpath, null, displayOutput, true);
-
- return getProcessOutput(arr, displayOutput);
- }
-
- /**
- * This function returns the output of the process as a string
- */
- public static String execJava(String[] args, String[] classpath, String[] envp,
- boolean displayOutput) throws IOException, InterruptedException {
- Object[] arr =
- execJavaCommon(args, classpath, envp, displayOutput, false);
-
- return getProcessOutput(arr, displayOutput);
- }
-
- public static String getProcessOutput(Object[] arr, boolean displayOutput)
+ public static ProcessBuilder javaProcessBuilder()
throws IOException, InterruptedException {
- Process proc = (Process) arr[0];
- StringBuilder output = new StringBuilder();
- InputStream in = proc.getInputStream();
- int result;
- byte[] bytes = new byte[1024];
-
- while ((result = in.read(bytes)) != -1) {
- output.append(new String(bytes, 0, result));
-
- if (displayOutput) {
- System.out.write(bytes, 0, result);
- }
- }
-
- in.close();
- proc.waitFor();
- checkStderr(arr);
- proc.destroy();
-
- return output.toString();
- }
-
- public static void checkStderr(Object[] execArgs) {
- StringBuilder errBuf = (StringBuilder) execArgs[1];
-
- synchronized (errBuf) {
- if (errBuf.length() > 0) {
- fail(errBuf.toString());
- }
- }
- }
-
- public static Object[] execJava2(String[] args, String[] classpath,
- boolean displayOutput) throws IOException, InterruptedException {
- return execJavaCommon(args, classpath, null, displayOutput, true);
- }
-
- private static Object[] execJavaCommon(String[] args, String[] classpath,
- String[] envp, boolean displayOutput, boolean appendToSystemClassPath)
- throws IOException, InterruptedException {
- // this function returns the resulting process from the exec
- ArrayList<String> execArgs = null;
- StringBuilder classPathString = new StringBuilder();
- StringBuilder command;
- String executable;
- String testVMArgs;
- StringTokenizer st;
-
- execArgs = new ArrayList<String>(3 + args.length);
+ ProcessBuilder builder = new ProcessBuilder();
// construct the name of executable file
- if (againstDalvik) {
- execArgs.add("dalvikvm");
- } else {
- execArgs.add("java");
- }
-
- // add classpath string
- if (classpath != null) {
- for (String element : classpath) {
- classPathString.append(File.pathSeparator);
- classPathString.append(element);
- }
- }
- if (appendToSystemClassPath) {
- execArgs.add("-cp");
- execArgs.add(System.getProperty("java.class.path") +
- classPathString);
- } else {
- if (classpath != null) {
- execArgs.add("-cp");
- execArgs.add(classPathString.toString());
- }
- }
+ builder.command().add(againstDalvik ? "dalvikvm" : "java");
// parse hy.test.vmargs if was given
- testVMArgs = System.getProperty("hy.test.vmargs");
+ String testVMArgs = System.getProperty("hy.test.vmargs");
if (testVMArgs != null) {
- st = new StringTokenizer(testVMArgs, " ");
-
- while (st.hasMoreTokens()) {
- execArgs.add(st.nextToken());
- }
+ builder.command().addAll(Arrays.asList(testVMArgs.split("\\s+")));
}
- // add custom args given as parameter
- for (String arg : args) {
- execArgs.add(arg);
- }
-
- if (displayOutput) {
- // Construct command line string and print it to stdout.
- command = new StringBuilder(execArgs.get(0));
- for (int i = 1; i < execArgs.size(); i++) {
- command.append(" ");
- command.append(execArgs.get(i));
- }
- }
-
- // execute java process
- return execAndDigestOutput(execArgs.toArray(new String[execArgs.size()]), envp);
+ return builder;
}
- //
- // mc: This looks like functionaly worth publicity:
- //
- public static Object[] execAndDigestOutput (String[] cmdLine, String[] envp)
- throws IOException, InterruptedException {
+ /**
+ * Returns a command-line ready path formed by joining the path elements
+ * with the system path separator as a separator.
+ */
+ public static String createPath(String... elements) {
+ StringBuilder result = new StringBuilder();
+ for (String element : elements) {
+ result.append(File.pathSeparator);
+ result.append(element);
+ }
+ return result.toString();
+ }
-// System.out.println("Commandline BEGIN");
-// for (int i = 0; i < cmdLine.length; i++) {
-// System.out.println(cmdLine[i]);
-// }
-// System.out.println("END");
+ /**
+ * Starts the specified process, collects its output from standard out and
+ * standard err, and returns. If the stream emits anything to standard err,
+ * an AssertionFailedError will be thrown.
+ *
+ * <p>This method assumes the target process will complete within ten
+ * seconds. If it does not, an AssertionFailedError will be thrown.
+ */
+ public static String execAndGetOutput(ProcessBuilder builder) throws IOException {
+ Process process = builder.start();
+ ExecutorService executorService = Executors.newFixedThreadPool(2);
+ try {
+ Future<String> errFuture = executorService.submit(
+ streamToStringCallable(process.getErrorStream()));
+ Future<String> outFuture = executorService.submit(
+ streamToStringCallable(process.getInputStream()));
- final Process proc = Runtime.getRuntime().exec(cmdLine, envp);
- final StringBuilder errBuf = new StringBuilder();
+ Throwable failure;
+ String out = "";
+ try {
+ out = outFuture.get(10, TimeUnit.SECONDS);
+ String err = errFuture.get(10, TimeUnit.SECONDS);
+ failure = err.length() > 0
+ ? new AssertionFailedError("Unexpected err stream data:\n" + err)
+ : null;
+ } catch (Exception e) {
+ failure = e;
+ }
- Thread errThread = new Thread(new Runnable() {
- public void run() {
- synchronized (errBuf) {
- InputStream err;
- int result;
- byte[] bytes = new byte[1024];
+ if (failure != null) {
+ AssertionFailedError error = new AssertionFailedError(
+ "Failed to execute " + builder.command() + "; output was:\n" + out);
+ error.initCause(failure);
+ throw error;
+ } else {
+ return out;
+ }
+ } finally {
+ executorService.shutdown();
+ }
+ }
- synchronized (proc) {
- proc.notifyAll();
- }
+ /**
+ * Starts the process described by 'builder', and asserts that it sees
+ * 'expectedOut' on stdout and 'expectedErr' on stderr. Times out after
+ * 10s.
+ */
+ public static void execAndCheckOutput(ProcessBuilder builder,
+ String expectedOut, String expectedErr) throws Exception {
+ Process process = builder.start();
+ ExecutorService executorService = Executors.newFixedThreadPool(2);
+ try {
+ Future<String> errFuture =
+ executorService.submit(streamToStringCallable(process.getErrorStream()));
+ Future<String> outFuture =
+ executorService.submit(streamToStringCallable(process.getInputStream()));
+ assertEquals(expectedOut, outFuture.get(10, TimeUnit.SECONDS));
+ assertEquals(expectedErr, errFuture.get(10, TimeUnit.SECONDS));
+ } finally {
+ executorService.shutdown();
+ process.waitFor();
+ }
+ }
- err = proc.getErrorStream();
- try {
- while ((result = err.read(bytes)) != -1) {
- System.err.write(bytes, 0, result);
- errBuf.append(new String(bytes));
- }
- err.close();
- } catch (IOException e) {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- PrintStream printer = new PrintStream(out);
-
- e.printStackTrace();
- e.printStackTrace(printer);
- printer.close();
- errBuf.append(new String(out.toByteArray()));
- }
+ private static Callable<String> streamToStringCallable(final InputStream in) {
+ return new Callable<String>() {
+ public String call() throws Exception {
+ StringWriter writer = new StringWriter();
+ Reader reader = new InputStreamReader(in);
+ int c;
+ while ((c = reader.read()) != -1) {
+ writer.write(c);
}
+ return writer.toString();
}
- });
-
- synchronized (proc) {
- errThread.start();
- // wait for errThread to start
- proc.wait();
- }
-
- return new Object[] { proc, errBuf };
+ };
}
-
}
diff --git a/support/src/test/java/tests/support/Support_TestWebServer.java b/support/src/test/java/tests/support/Support_TestWebServer.java
index 609e993..8c88cc0 100644
--- a/support/src/test/java/tests/support/Support_TestWebServer.java
+++ b/support/src/test/java/tests/support/Support_TestWebServer.java
@@ -39,22 +39,13 @@
/* The ANDROID_LOG_TAG */
private final static String LOGTAG = "httpsv";
- /* Where worker threads stand idle */
- Vector threads = new Vector();
-
/** maps the recently requested URLs to the full request snapshot */
private final Map<String, Request> pathToRequest
= new ConcurrentHashMap<String, Request>();
- /* List of all active worker threads */
- Vector activeThreads = new Vector();
-
/* timeout on client connections */
int timeout = 0;
- /* max # worker threads */
- int workers = 5;
-
/* Default port for this server to listen on */
final static int DEFAULT_PORT = 8080;
@@ -283,19 +274,7 @@
running = false;
}
- Worker w = null;
- synchronized (threads) {
- if (threads.isEmpty()) {
- Worker ws = new Worker();
- ws.setSocket(s);
- activeThreads.addElement(ws);
- (new Thread(ws, "additional worker")).start();
- } else {
- w = (Worker) threads.elementAt(0);
- threads.removeElementAt(0);
- w.setSocket(s);
- }
- }
+ new Thread(new Worker(s), "additional worker").start();
}
} catch (SocketException e) {
log("SocketException in AcceptThread: probably closed during accept");
@@ -316,14 +295,6 @@
therefore the acceptLimit functionality has been added
to circumvent this limitation */
ss.close();
-
- // Stop worker threads from continuing
- for (Enumeration e = activeThreads.elements(); e.hasMoreElements();) {
- Worker w = (Worker)e.nextElement();
- w.close();
- }
- activeThreads.clear();
-
} catch (IOException e) {
/* We are shutting down the server, so we expect
* things to die. Don't propagate.
@@ -393,75 +364,20 @@
/* Indicates whether current request has any data content */
private boolean hasContent = false;
- boolean running = false;
-
/* Request headers are stored here */
private Map<String, String> headers = new LinkedHashMap<String, String>();
/* Create a new worker thread */
- Worker() {
- buf = new byte[BUF_SIZE];
- s = null;
- }
-
- /**
- * Called by the AcceptThread to unblock this Worker to process
- * a request.
- * @param s The socket on which the connection has been made
- */
- synchronized void setSocket(Socket s) {
+ Worker(Socket s) {
+ this.buf = new byte[BUF_SIZE];
this.s = s;
- notify();
}
- /**
- * Called by the accept thread when it's closing. Potentially unblocks
- * the worker thread to terminate properly
- */
- synchronized void close() {
- running = false;
- notify();
- }
-
- /**
- * Main worker thread. This will wait until a request has
- * been identified by the accept thread upon which it will
- * service the thread.
- */
public synchronized void run() {
- running = true;
- while(running) {
- if (s == null) {
- /* nothing to do */
- try {
- log(this+" Moving to wait state");
- wait();
- } catch (InterruptedException e) {
- /* should not happen */
- continue;
- }
- if (!running) break;
- }
- try {
- handleClient();
- } catch (Exception e) {
- log("Exception during handleClient in the TestWebServer: "
- + e.getMessage());
- }
- /* go back in wait queue if there's fewer
- * than numHandler connections.
- */
- s = null;
- Vector pool = threads;
- synchronized (pool) {
- if (pool.size() >= workers) {
- /* too many threads, exit this one */
- activeThreads.remove(this);
- return;
- } else {
- pool.addElement(this);
- }
- }
+ try {
+ handleClient();
+ } catch (Exception e) {
+ log("Exception during handleClient in the TestWebServer: " + e.getMessage());
}
log(this+" terminated");
}
diff --git a/support/src/test/java/tests/support/ThrowingReader.java b/support/src/test/java/tests/support/ThrowingReader.java
new file mode 100644
index 0000000..fbefeb1
--- /dev/null
+++ b/support/src/test/java/tests/support/ThrowingReader.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.support;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * A reader that always throws after a predetermined number of bytes have been
+ * read.
+ */
+public class ThrowingReader extends FilterReader {
+
+ private int total = 0;
+ private int throwAt;
+
+ public ThrowingReader(Reader in, int throwAt) {
+ super(in);
+ this.throwAt = throwAt;
+ }
+
+ @Override public int read() throws IOException {
+ explodeIfNecessary();
+ int result = super.read();
+ total++;
+ return result;
+ }
+
+ @Override public int read(char[] buf, int offset, int count)
+ throws IOException {
+ explodeIfNecessary();
+
+ if (total < throwAt) {
+ count = Math.min(count, (throwAt - total));
+ }
+
+ int returned = super.read(buf, offset, count);
+ total += returned;
+ return returned;
+ }
+
+ private void explodeIfNecessary() throws IOException {
+ if (total == throwAt) {
+ throwAt = Integer.MAX_VALUE;
+ throw new IOException();
+ }
+ }
+}
diff --git a/support/src/test/java/tests/util/PrefsTester.java b/support/src/test/java/tests/util/PrefsTester.java
deleted file mode 100644
index 047b357..0000000
--- a/support/src/test/java/tests/util/PrefsTester.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.util;
-
-import java.util.prefs.BackingStoreException;
-import java.util.prefs.Preferences;
-import java.util.Arrays;
-
-/**
- * Prepares the shared preferences store for a test by wiping preference data
- * before and after the test. Sample usage:
- * <pre>
- * public void MyPreferencesTest extends TestCase {
- * private final PrefsTester prefsTester = new PrefsTester();
- *
- * public void setUp() throws BackingStoreException {
- * super.setUp();
- * prefsTester.setUp();
- * }
- *
- * public void tearDown() throws BackingStoreException {
- * prefsTester.tearDown();
- * super.tearDown();
- * }
- *
- * ...
- * }</pre>
- *
- * <p>Once the preferences classes have been initialized, the path where their
- * data is stored is fixed. For that reason, every test that reads or writes
- * preferences must first prepare preferences for testing by using this class.
- */
-public final class PrefsTester {
-
- static {
- String tmp = System.getProperty("java.io.tmpdir");
- System.setProperty("user.home", tmp);
- System.setProperty("java.home", tmp);
- }
-
- public void setUp() throws BackingStoreException {
- clear();
- }
-
- public void tearDown() throws BackingStoreException {
- clear();
- }
-
- private void clear() throws BackingStoreException {
- for (Preferences root : Arrays .asList(
- Preferences.systemRoot(), Preferences.userRoot())) {
- for (String child : root.childrenNames()) {
- root.node(child).removeNode();
- }
- root.clear();
- root.flush();
- }
- }
-}
diff --git a/support/src/test/java/tests/util/TestEnvironment.java b/support/src/test/java/tests/util/TestEnvironment.java
new file mode 100644
index 0000000..92facda
--- /dev/null
+++ b/support/src/test/java/tests/util/TestEnvironment.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.util;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+/**
+ * Prepares system properties and preferences to hygienic values for testing:
+ * <ul>
+ * <li>System properties are set to reasonable defaults. Referenced
+ * directories such as the user and Java home directories will be
+ * writable.
+ * <li>System and user preferences are cleared. Once the preferences classes
+ * have been initialized, the path where their data is stored is fixed.
+ * For this reason, every test that reads or writes preferences should
+ * first reset the system configuration with this API.
+ * </ul>
+ *
+ * <p>Use this class to clean up before and/or after your test. Sample usage:
+ * <pre>
+ * public void MyTest extends TestCase {
+ *
+ * protected void setUp() throws Exception {
+ * super.setUp();
+ * TestEnvironment().reset();
+ * }
+ *
+ * protected void tearDown() throws Exception {
+ * TestEnvironment().reset();
+ * super.tearDown();
+ * }
+ *
+ * ...
+ * }</pre>
+ */
+public final class TestEnvironment {
+ private TestEnvironment() {}
+
+ public static synchronized void reset() {
+ resetSystemProperties();
+ resetPreferences();
+
+ // TODO: TimeZone?, SecurityManager?
+ }
+
+ private static void resetSystemProperties() {
+ String tmpDir = System.getProperty("java.io.tmpdir");
+ if (tmpDir == null) {
+ throw new IllegalStateException("Test execution requires the"
+ + " system property java.io.tmpdir to be set.");
+ }
+
+ Properties p = new Properties();
+
+ // runtime properties that we never want to clobber
+ copyProperty(p, "android.vm.dexfile");
+ copyProperty(p, "java.boot.class.path");
+ copyProperty(p, "java.class.path");
+ copyProperty(p, "java.io.tmpdir");
+ copyProperty(p, "java.library.path");
+ copyProperty(p, "os.arch");
+ copyProperty(p, "os.name");
+ copyProperty(p, "os.version");
+
+ // paths with writable values for testing
+ String userHome = tmpDir + "/user.home";
+ String javaHome = tmpDir + "/java.home";
+ String userDir = tmpDir + "/user.dir";
+ makeDirectory(new File(userHome));
+ makeDirectory(new File(javaHome));
+ makeDirectory(new File(userDir));
+ p.put("java.home", javaHome);
+ p.put("user.dir", userDir);
+ p.put("user.home", userHome);
+
+ // hardcoded properties
+ p.put("file.encoding", "UTF-8");
+ p.put("file.separator", "/");
+ p.put("java.class.version", "46.0");
+ p.put("java.compiler", "");
+ p.put("java.ext.dirs", "");
+ p.put("java.net.preferIPv6Addresses", "true");
+ p.put("java.runtime.name", "Android Runtime");
+ p.put("java.runtime.version", "0.9");
+ p.put("java.specification.name", "Dalvik Core Library");
+ p.put("java.specification.vendor", "The Android Project");
+ p.put("java.specification.version", "0.9");
+ p.put("java.vendor", "The Android Project");
+ p.put("java.vendor.url", "http://www.android.com/");
+ p.put("java.version", "0");
+ p.put("java.vm.name", "Dalvik");
+ p.put("java.vm.specification.name", "Dalvik Virtual Machine Specification");
+ p.put("java.vm.specification.vendor", "The Android Project");
+ p.put("java.vm.specification.version", "0.9");
+ p.put("java.vm.vendor", "The Android Project");
+ p.put("java.vm.vendor.url", "http://www.android.com/");
+ p.put("java.vm.version", "1.2.0");
+ p.put("javax.net.ssl.trustStore", "/etc/security/cacerts.bks");
+ p.put("line.separator", "\n");
+ p.put("path.separator", ":");
+ p.put("user.language", "en");
+ p.put("user.name", "");
+ p.put("user.region", "US");
+
+ System.setProperties(p);
+ }
+
+ private static void copyProperty(Properties p, String key) {
+ p.put(key, System.getProperty(key));
+ }
+
+ private static void makeDirectory(File path) {
+ boolean success;
+ if (!path.exists()) {
+ success = path.mkdirs();
+ } else if (!path.isDirectory()) {
+ success = path.delete() && path.mkdirs();
+ } else {
+ success = true;
+ }
+
+ if (!success) {
+ throw new RuntimeException("Failed to make directory " + path);
+ }
+ }
+
+ private static void resetPreferences() {
+ try {
+ for (Preferences root : Arrays.asList(
+ Preferences.systemRoot(), Preferences.userRoot())) {
+ for (String child : root.childrenNames()) {
+ root.node(child).removeNode();
+ }
+ root.clear();
+ root.flush();
+ }
+ } catch (BackingStoreException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/text/src/main/java/java/text/AttributedString.java b/text/src/main/java/java/text/AttributedString.java
index 77bbf78..fe7aa0c 100644
--- a/text/src/main/java/java/text/AttributedString.java
+++ b/text/src/main/java/java/text/AttributedString.java
@@ -107,7 +107,7 @@
}
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/text/src/main/java/java/text/BreakIterator.java b/text/src/main/java/java/text/BreakIterator.java
index 7d19179..78870f0 100644
--- a/text/src/main/java/java/text/BreakIterator.java
+++ b/text/src/main/java/java/text/BreakIterator.java
@@ -23,6 +23,8 @@
import java.util.Locale;
+import org.apache.harmony.text.internal.nls.Messages;
+
/**
* Locates boundaries in text. This class defines a protocol for objects that
* break up a piece of natural-language text according to a set of criteria.
@@ -522,7 +524,7 @@
cloned.wrapped = (com.ibm.icu4jni.text.BreakIterator) wrapped.clone();
return cloned;
} catch (CloneNotSupportedException e) {
- throw new InternalError(e.getMessage());
+ throw new AssertionError(e); // android-changed
}
}
@@ -542,11 +544,10 @@
* greater than the length of {@code buf}.
*/
protected static long getLong(byte[] buf, int offset) {
- if (null == buf) {
- throw new NullPointerException();
- }
- if (offset < 0 || buf.length - offset < LONG_LENGTH) {
- throw new ArrayIndexOutOfBoundsException();
+ // Force a buf null check first!
+ if (buf.length - offset < LONG_LENGTH || offset < 0) {
+ // text.1E=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Messages.getString("text.1E", offset)); //$NON-NLS-1$
}
long result = 0;
for (int i = offset; i < offset + LONG_LENGTH; i++) {
@@ -571,11 +572,10 @@
* greater than the length of {@code buf}.
*/
protected static int getInt(byte[] buf, int offset) {
- if (null == buf) {
- throw new NullPointerException();
- }
- if (offset < 0 || buf.length - INT_LENGTH < offset) {
- throw new ArrayIndexOutOfBoundsException();
+ // Force buf null check first!
+ if (buf.length - INT_LENGTH < offset || offset < 0) {
+ // text.1E=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Messages.getString("text.1E", offset)); //$NON-NLS-1$
}
int result = 0;
for (int i = offset; i < offset + INT_LENGTH; i++) {
@@ -600,11 +600,10 @@
* greater than the length of {@code buf}.
*/
protected static short getShort(byte[] buf, int offset) {
- if (null == buf) {
- throw new NullPointerException();
- }
- if (offset < 0 || buf.length - SHORT_LENGTH < offset) {
- throw new ArrayIndexOutOfBoundsException();
+ // Force buf null check first!
+ if (buf.length - SHORT_LENGTH < offset || offset < 0) {
+ // text.1E=Offset out of bounds \: {0}
+ throw new ArrayIndexOutOfBoundsException(Messages.getString("text.1E", offset)); //$NON-NLS-1$
}
short result = 0;
for (int i = offset; i < offset + SHORT_LENGTH; i++) {
diff --git a/text/src/main/java/java/text/Collator.java b/text/src/main/java/java/text/Collator.java
index aaa3e12..e954b8b 100644
--- a/text/src/main/java/java/text/Collator.java
+++ b/text/src/main/java/java/text/Collator.java
@@ -22,12 +22,11 @@
package java.text;
import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Comparator;
import java.util.Locale;
import java.util.Vector;
-import org.apache.harmony.luni.util.PriviAction;
-
/**
* Performs locale-sensitive string comparison. A concrete subclass,
* {@link RuleBasedCollator}, allows customization of the collation ordering by
@@ -163,7 +162,11 @@
static {
// CACHE_SIZE includes key and value, so needs to be double
String cacheSize = AccessController
- .doPrivileged(new PriviAction<String>("collator.cache")); //$NON-NLS-1$
+ .doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty("collator.cache"); //$NON-NLS-1$
+ }
+ });
if (cacheSize != null) {
try {
CACHE_SIZE = Integer.parseInt(cacheSize);
@@ -208,7 +211,7 @@
clone.icuColl = (com.ibm.icu4jni.text.Collator) this.icuColl.clone();
return clone;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/text/src/main/java/java/text/DateFormat.java b/text/src/main/java/java/text/DateFormat.java
index f39965a..531bed8 100644
--- a/text/src/main/java/java/text/DateFormat.java
+++ b/text/src/main/java/java/text/DateFormat.java
@@ -666,7 +666,7 @@
public Date parse(String string) throws ParseException {
ParsePosition position = new ParsePosition(0);
Date date = parse(string, position);
- if (position.getErrorIndex() != -1 || position.getIndex() == 0) {
+ if (position.getIndex() == 0) {
// text.19=Unparseable date: {0}
throw new ParseException(
Messages.getString("text.19", string), position.getErrorIndex()); //$NON-NLS-1$
diff --git a/text/src/main/java/java/text/DecimalFormatSymbols.java b/text/src/main/java/java/text/DecimalFormatSymbols.java
index a71a4c6..46849ef 100644
--- a/text/src/main/java/java/text/DecimalFormatSymbols.java
+++ b/text/src/main/java/java/text/DecimalFormatSymbols.java
@@ -115,7 +115,7 @@
symbols.patternChars = patternChars.clone();
return symbols;
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/text/src/main/java/java/text/Format.java b/text/src/main/java/java/text/Format.java
index 6ee1ba2..8abe605 100644
--- a/text/src/main/java/java/text/Format.java
+++ b/text/src/main/java/java/text/Format.java
@@ -84,7 +84,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
@@ -202,8 +202,10 @@
public Object parseObject(String string) throws ParseException {
ParsePosition position = new ParsePosition(0);
Object result = parseObject(string, position);
- if (position.getErrorIndex() != -1 || position.getIndex() == 0) {
- throw new ParseException(null, position.getErrorIndex());
+ if (position.getIndex() == 0) {
+ // text.1C=Format.parseObject(String) parse failure
+ throw new ParseException(
+ Messages.getString("text.1C"), position.getErrorIndex()); //$NON-NLS-1$
}
return result;
}
diff --git a/text/src/main/java/java/text/MessageFormat.java b/text/src/main/java/java/text/MessageFormat.java
index 4ab1ade..f6074b2 100644
--- a/text/src/main/java/java/text/MessageFormat.java
+++ b/text/src/main/java/java/text/MessageFormat.java
@@ -859,8 +859,10 @@
public Object[] parse(String string) throws ParseException {
ParsePosition position = new ParsePosition(0);
Object[] result = parse(string, position);
- if (position.getErrorIndex() != -1 || position.getIndex() == 0) {
- throw new ParseException(null, position.getErrorIndex());
+ if (position.getIndex() == 0) {
+ // text.1B=MessageFormat.parseObject(String) parse failure
+ throw new ParseException(
+ Messages.getString("text.1B"), position.getErrorIndex()); //$NON-NLS-1$
}
return result;
}
diff --git a/text/src/main/java/java/text/NumberFormat.java b/text/src/main/java/java/text/NumberFormat.java
index 5b8d883..87f17c1 100644
--- a/text/src/main/java/java/text/NumberFormat.java
+++ b/text/src/main/java/java/text/NumberFormat.java
@@ -555,8 +555,10 @@
public Number parse(String string) throws ParseException {
ParsePosition pos = new ParsePosition(0);
Number number = parse(string, pos);
- if (pos.getErrorIndex() != -1 || pos.getIndex() == 0) {
- throw new ParseException(null, pos.getErrorIndex());
+ if (pos.getIndex() == 0) {
+ // text.1D=Unparseable number: {0}
+ throw new ParseException(
+ Messages.getString("text.1D", string), pos.getErrorIndex()); //$NON-NLS-1$
}
return number;
}
diff --git a/text/src/main/java/java/text/StringCharacterIterator.java b/text/src/main/java/java/text/StringCharacterIterator.java
index 8ef0341..ea60180 100644
--- a/text/src/main/java/java/text/StringCharacterIterator.java
+++ b/text/src/main/java/java/text/StringCharacterIterator.java
@@ -105,7 +105,7 @@
try {
return super.clone();
} catch (CloneNotSupportedException e) {
- return null;
+ throw new AssertionError(e); // android-changed
}
}
diff --git a/text/src/main/java/org/apache/harmony/text/internal/nls/messages.properties b/text/src/main/java/org/apache/harmony/text/internal/nls/messages.properties
index 22221a9..b80cde2 100644
--- a/text/src/main/java/org/apache/harmony/text/internal/nls/messages.properties
+++ b/text/src/main/java/org/apache/harmony/text/internal/nls/messages.properties
@@ -43,4 +43,7 @@
text.18=Not a valid {0}, subclass should override readResolve()
text.19=Unparseable date: {0}
text.1A=position is null
-
+text.1B=MessageFormat.parseObject(String) parse failure
+text.1C=Format.parseObject(String) parse failure
+text.1D=Unparseable number: {0}
+text.1E=Offset out of bounds \: {0}
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationKeyTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationKeyTest.java
index d1a7c42..c2135c3 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationKeyTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationKeyTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.harmony.text.tests.java.text;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -127,7 +126,6 @@
method = "toByteArray",
args = {}
)
- @KnownFailure("This test fails on Harmony ClassLibrary.")
public void test_toByteArray() {
// Test for method byte [] java.text.CollationKey.toByteArray()
Collator collator = Collator.getInstance();
@@ -142,7 +140,6 @@
fail("ParseException");
return;
}
- bytes = collator.getCollationKey("1234567").toByteArray();
/*
* CollationElementIterator it =
* ((RuleBasedCollator)collator).getCollationElementIterator("1234567");
@@ -152,8 +149,51 @@
* i+=2) { System.out.print(Integer.toHexString(bytes[i]) +
* Integer.toHexString(bytes[i+1]) + " "); } System.out.println();
*/
- byte[] result = new byte[] { 0, 2, 0, 2, 0, 2, 0, 0, 0, 3, 0, 3, 0, 1,
- 0, 2, 0, 2, 0, 0, 0, 4, 0, 4, 0, 1, 0, 1, 0, 2 };
- assertTrue("Wrong bytes", Arrays.equals(bytes, result));
+
+ // The RI has a different algorithm to generate the collation keys.
+ // bytes = collator.getCollationKey("1234567").toByteArray();
+ // byte[] result = new byte[] { 0, 2, 0, 2, 0, 2, 0, 0, 0, 3, 0, 3, 0, 1,
+ // 0, 2, 0, 2, 0, 0, 0, 4, 0, 4, 0, 1, 0, 1, 0, 2 };
+ byte[] bytes1 = collator.getCollationKey("12").toByteArray();
+ byte[] bytes2 = collator.getCollationKey("123").toByteArray();
+ byte[] bytes3 = collator.getCollationKey("124").toByteArray();
+ byte[] bytes4 = collator.getCollationKey("1245").toByteArray();
+ byte[] bytes5 = collator.getCollationKey("1245").toByteArray();
+
+ assertTrue("returned collation key does not sort correctly",
+ compareUnsignedByteArrays(bytes1, bytes2) < 0);
+
+ assertTrue("returned collation key does not sort correctly",
+ compareUnsignedByteArrays(bytes2, bytes3) < 0);
+
+ assertTrue("returned collation key does not sort correctly",
+ compareUnsignedByteArrays(bytes3, bytes4) < 0);
+
+ assertTrue("returned collation key does not sort correctly",
+ compareUnsignedByteArrays(bytes4, bytes5) == 0);
+
+ }
+
+ private int compareUnsignedByteArrays(byte[] bytes1, byte[] bytes2) {
+ int commonLength = Math.min(bytes1.length, bytes2.length);
+
+ for (int i = 0; i < commonLength; i++) {
+ int keyA = bytes1[i] & 0xFF;
+ int keyB = bytes2[i] & 0xFF;
+ if (keyA < keyB) {
+ return -1;
+ }
+ if (keyA > keyB) {
+ return 1;
+ }
+ }
+
+ if (bytes1.length < bytes2.length) {
+ return -1;
+ } else if (bytes1.length > bytes2.length) {
+ return 1;
+ } else {
+ return 0;
+ }
}
}
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatTest.java
index e7609a8..e636a07 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatTest.java
@@ -182,7 +182,6 @@
method = "getAvailableLocales",
args = {}
)
- @KnownFailure("German locales were removed last minute in cupcake")
public void test_getAvailableLocales() {
Locale[] locales = DateFormat.getAvailableLocales();
assertTrue("No locales", locales.length > 0);
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
index 47107cd..542ad7f 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
@@ -146,7 +146,6 @@
method = "getCurrency",
args = {}
)
- @KnownFailure("some locales were removed last minute in cupcake")
public void test_getCurrency() {
Currency currency = Currency.getInstance("USD");
assertEquals("Returned incorrect currency",
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
index aa36abc..edab40b 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
@@ -78,6 +78,29 @@
String result;
char current;
+ // For BigDecimal with multiplier test.
+ DecimalFormat df = new DecimalFormat();
+ df.setMultiplier(10);
+ iterator = df.formatToCharacterIterator(new BigDecimal("12345678901234567890"));
+ result = "123,456,789,012,345,678,900";
+ current = iterator.current();
+ for (int i = 0; i < result.length(); i++) {
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+
+ // For BigDecimal with multiplier test.
+ df = new DecimalFormat();
+ df.setMultiplier(-1);
+ df.setMaximumFractionDigits(20);
+ iterator = df.formatToCharacterIterator(new BigDecimal("1.23456789012345678901"));
+ result = "-1.23456789012345678901";
+ current = iterator.current();
+ for (int i = 0; i < result.length(); i++) {
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+
iterator = new DecimalFormat()
.formatToCharacterIterator(new BigDecimal("1.23456789E1234"));
runStarts = new int[] {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14};
@@ -1807,7 +1830,6 @@
method = "formatToCharacterIterator",
args = {java.lang.Object.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatToCharacterIteratorLjava_lang_Object() {
try {
@@ -2438,7 +2460,6 @@
method = "!SerializationGolden",
args = {}
)
- @KnownFailure("a regression. This didn't fail before")
public void test_serializationHarmonyRICompatible() throws Exception {
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
@@ -2547,4 +2568,119 @@
DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance();
format.setDecimalFormatSymbols(null);
}
+
+ private void assertBigDecimalWithFraction(
+ BigDecimal bd,
+ String expectedResult,
+ int fraction) {
+ NumberFormat pf = NumberFormat.getPercentInstance();
+ pf.setMaximumFractionDigits(fraction);
+ assertEquals(expectedResult, pf.format(bd));
+ }
+
+ private void assertDecFmtWithMultiplierAndFraction(
+ String value,
+ int multiplier,
+ int fraction,
+ String expectedResult) {
+
+ DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
+ df.setMultiplier(multiplier);
+ df.setMaximumFractionDigits(fraction);
+ BigDecimal d = new BigDecimal(value);
+ assertEquals(expectedResult, df.format(d));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Regression test for some existing bugs and crashes",
+ method = "format",
+ args = { String.class, Object[].class }
+ )
+ public void testBigDecimalBug1897917() {
+ // Bug1897917 : BigDecimal does not take into account multiplier.
+ // So the BigDecimal 0.17 formatted in PercentInstance is 0% instead of 17%.
+
+ NumberFormat pf = NumberFormat.getPercentInstance();
+
+ // Test bug 1897917 case.
+ assertEquals("17%", pf.format(BigDecimal.valueOf(0.17)));
+
+ // Test long decimal formatted in PercentInstance with various fractions.
+ String longDec = "11.2345678901234567890123456789012345678901234567890";
+ BigDecimal bd = new BigDecimal(longDec);
+ assertBigDecimalWithFraction(bd, "1,123.46%", 2);
+ assertBigDecimalWithFraction(bd, "1,123.45678901%", 8);
+ assertBigDecimalWithFraction(bd, "1,123.4567890123%", 10);
+ assertBigDecimalWithFraction(bd, "1,123.45678901234567890123%", 20);
+ assertBigDecimalWithFraction(bd, "1,123.456789012345678901234567890123%", 30);
+
+ // Test trailing zeros.
+ assertDecFmtWithMultiplierAndFraction("3333.33333333", 3, 4, "10,000");
+ assertDecFmtWithMultiplierAndFraction("3333.33333333", -3, 4, "-10,000");
+ assertDecFmtWithMultiplierAndFraction("0.00333333", 3, 4, "0.01");
+ assertDecFmtWithMultiplierAndFraction("3330000000000000000000000000000000", 3, 4,
+ "9,990,000,000,000,000,000,000,000,000,000,000");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Regression test for some existing bugs and crashes",
+ method = "format",
+ args = { String.class, Object[].class }
+ )
+ public void testBigDecimalTestBigIntWithMultiplier() {
+ // Big integer tests.
+ assertDecFmtWithMultiplierAndFraction("123456789012345", 10, 0, "1,234,567,890,123,450");
+ assertDecFmtWithMultiplierAndFraction("12345678901234567890", 10, 0,
+ "123,456,789,012,345,678,900");
+ assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", 10, 0,
+ "987,654,321,098,765,432,109,876,543,210");
+
+ assertDecFmtWithMultiplierAndFraction("123456789012345", -10, 0, "-1,234,567,890,123,450");
+ assertDecFmtWithMultiplierAndFraction("12345678901234567890", -10, 0,
+ "-123,456,789,012,345,678,900");
+ assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", -10, 0,
+ "-987,654,321,098,765,432,109,876,543,210");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Regression test for some existing bugs and crashes",
+ method = "format",
+ args = { String.class, Object[].class }
+ )
+ public void testBigDecimalICUConsistency() {
+ DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
+ df.setMaximumFractionDigits(2);
+ df.setMultiplier(2);
+ assertEquals(df.format(BigDecimal.valueOf(0.16)),
+ df.format(BigDecimal.valueOf(0.16).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0.0293)),
+ df.format(BigDecimal.valueOf(0.0293).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0.006)),
+ df.format(BigDecimal.valueOf(0.006).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0.00283)),
+ df.format(BigDecimal.valueOf(0.00283).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(1.60)),
+ df.format(BigDecimal.valueOf(1.60).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(15)),
+ df.format(BigDecimal.valueOf(15).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(170)),
+ df.format(BigDecimal.valueOf(170).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(234.56)),
+ df.format(BigDecimal.valueOf(234.56).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(0)),
+ df.format(BigDecimal.valueOf(0).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(-1)),
+ df.format(BigDecimal.valueOf(-1).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(-10000)),
+ df.format(BigDecimal.valueOf(-10000).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(-0.001)),
+ df.format(BigDecimal.valueOf(-0.001).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
+ df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
+ assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
+ df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+ }
}
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatTest.java
index 0480704..d1246d3 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatTest.java
@@ -143,7 +143,6 @@
method = "getIntegerInstance",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getIntegerInstanceLjava_util_Locale()
throws ParseException {
// Test for method java.text.NumberFormat
@@ -319,7 +318,6 @@
method = "parseObject",
args = {java.lang.String.class, java.text.ParsePosition.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_parseObjectLjava_lang_StringLjava_text_ParsePosition() {
// regression test for HARMONY-1003
assertNull(NumberFormat.getInstance().parseObject("0",
@@ -452,7 +450,6 @@
method = "format",
args = {double.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLdouble() {
// BEGIN android-changed
NumberFormat nf1 = NumberFormat.getInstance(Locale.US);
@@ -492,7 +489,6 @@
method = "format",
args = {long.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_formatLlong() {
// BEGIN android-changed
NumberFormat nf1 = NumberFormat.getInstance(Locale.US);
@@ -591,7 +587,6 @@
method = "getCurrencyInstance",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getCurrencyInstanceLjava_util_Locale() {
// BEGIN android-changed
Locale usLocale = Locale.US;
@@ -693,7 +688,6 @@
method = "getInstance",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getInstanceLjava_util_Locale() {
// BEGIN android-changed
Locale.setDefault(Locale.US);
@@ -770,7 +764,6 @@
method = "getNumberInstance",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getNumberInstanceLjava_util_Locale() {
// BEGIN android-changed
Locale.setDefault(Locale.US);
@@ -849,7 +842,6 @@
method = "getPercentInstance",
args = {java.util.Locale.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_getPercentInstanceLjava_util_Locale() {
Locale.setDefault(Locale.US);
NumberFormat format = NumberFormat.getPercentInstance(new Locale("cs",
@@ -1061,7 +1053,6 @@
method = "setGroupingUsed",
args = {boolean.class}
)
- @KnownFailure("Some locales were removed last minute in cupcake")
public void test_setGroupingUsed() {
NumberFormat nf1 = NumberFormat.getInstance(Locale.US);
nf1.setGroupingUsed(false);
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/ParseExceptionTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/ParseExceptionTest.java
index 1c2da6a..3bcc38c 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/ParseExceptionTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/ParseExceptionTest.java
@@ -37,15 +37,13 @@
args = {java.lang.String.class, int.class}
)
public void test_ConstructorLjava_lang_StringI() {
- // Test for method java.text.ParseException(java.lang.String, int)
- // SM
try {
DateFormat df = DateFormat.getInstance();
df.parse("HelloWorld");
+ fail("ParseException not created/thrown.");
} catch (ParseException e) {
- return;
+ // expected
}
- fail("ParseException not created/thrown.");
}
/**
@@ -58,8 +56,6 @@
args = {}
)
public void test_getErrorOffset() {
- // Test for method int java.text.ParseException.getErrorOffset()
- // SM
try {
DateFormat df = DateFormat.getInstance();
df.parse("1999HelloWorld");
@@ -67,18 +63,4 @@
assertEquals("getErrorOffsetFailed.", 4, e.getErrorOffset());
}
}
-
- /**
- * Sets up the fixture, for example, open a network connection. This method
- * is called before a test is executed.
- */
- protected void setUp() {
- }
-
- /**
- * Tears down the fixture, for example, close a network connection. This
- * method is called after a test is executed.
- */
- protected void tearDown() {
- }
}
diff --git a/tools/dalvik_jtreg/Android.mk b/tools/dalvik_jtreg/Android.mk
new file mode 100644
index 0000000..7da7212
--- /dev/null
+++ b/tools/dalvik_jtreg/Android.mk
@@ -0,0 +1,41 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ java/dalvik/jtreg/Adb.java \
+ java/dalvik/jtreg/Command.java \
+ java/dalvik/jtreg/CommandFailedException.java \
+ java/dalvik/jtreg/Dx.java \
+ java/dalvik/jtreg/ExpectedResult.java \
+ java/dalvik/jtreg/Javac.java \
+ java/dalvik/jtreg/JtregRunner.java \
+ java/dalvik/jtreg/Result.java \
+ java/dalvik/jtreg/Strings.java \
+ java/dalvik/jtreg/TestRun.java \
+ java/dalvik/jtreg/TestDescriptions.java \
+ java/dalvik/jtreg/TestRunner.java \
+ java/dalvik/jtreg/TestToDex.java \
+ java/dalvik/jtreg/XmlReportPrinter.java \
+
+LOCAL_MODULE:= dalvik_jtreg
+LOCAL_STATIC_JAVA_LIBRARIES := javatest jh jtreg kxml2-2.3.0
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-subdir-makefiles)
+
+# prebuilt javatest.jar
+include $(CLEAR_VARS)
+LOCAL_PREBUILT_JAVA_LIBRARIES := javatest:lib/javatest.jar
+include $(BUILD_HOST_PREBUILT)
+
+# prebuilt jh.jar
+include $(CLEAR_VARS)
+LOCAL_PREBUILT_JAVA_LIBRARIES := jh:lib/jh.jar
+include $(BUILD_HOST_PREBUILT)
+
+# prebuilt jtreg.jar
+include $(CLEAR_VARS)
+LOCAL_PREBUILT_JAVA_LIBRARIES := jtreg:lib/jtreg.jar
+include $(BUILD_HOST_PREBUILT)
diff --git a/tools/dalvik_jtreg/expectations/java.util.Arrays.Big.expected b/tools/dalvik_jtreg/expectations/java.util.Arrays.Big.expected
new file mode 100644
index 0000000..4d1156b
--- /dev/null
+++ b/tools/dalvik_jtreg/expectations/java.util.Arrays.Big.expected
@@ -0,0 +1,2 @@
+result=COMPILE_FAILED
+pattern=.*cannot find symbol.*
\ No newline at end of file
diff --git a/tools/dalvik_jtreg/expectations/java.util.Arrays.CopyMethods.expected b/tools/dalvik_jtreg/expectations/java.util.Arrays.CopyMethods.expected
new file mode 100644
index 0000000..4d1156b
--- /dev/null
+++ b/tools/dalvik_jtreg/expectations/java.util.Arrays.CopyMethods.expected
@@ -0,0 +1,2 @@
+result=COMPILE_FAILED
+pattern=.*cannot find symbol.*
\ No newline at end of file
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/Adb.java b/tools/dalvik_jtreg/java/dalvik/jtreg/Adb.java
new file mode 100644
index 0000000..ef8508e
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/Adb.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import java.io.File;
+
+/**
+ * An adb command.
+ */
+final class Adb {
+
+ public void mkdir(File name) {
+ new Command("adb", "shell", "mkdir", name.toString()).execute();
+ }
+
+ public void rm(File name) {
+ new Command("adb", "shell", "rm", "-r", name.toString()).execute();
+ }
+
+ public void push(File local, File remote) {
+ new Command("adb", "push", local.toString(), remote.toString())
+ .execute();
+ }
+
+ public void forwardTcp(int localPort, int devicePort) {
+ new Command("adb", "forward", "tcp:" + localPort, "tcp:" + devicePort)
+ .execute();
+ }
+}
\ No newline at end of file
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/Command.java b/tools/dalvik_jtreg/java/dalvik/jtreg/Command.java
new file mode 100644
index 0000000..9682a18
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/Command.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * An out of process executable.
+ */
+final class Command {
+
+ private final List<String> args;
+ private final boolean permitNonZeroExitStatus;
+ private Process process;
+
+ Command(String... args) {
+ this(Arrays.asList(args));
+ }
+
+ Command(List<String> args) {
+ this.args = new ArrayList<String>(args);
+ this.permitNonZeroExitStatus = false;
+ }
+
+ private Command(Builder builder) {
+ this.args = new ArrayList<String>(builder.args);
+ this.permitNonZeroExitStatus = builder.permitNonZeroExitStatus;
+ }
+
+ static String path(Object... objects) {
+ return Strings.join(objects, ":");
+ }
+
+ public synchronized void start() throws IOException {
+ if (isStarted()) {
+ throw new IllegalStateException("Already started!");
+ }
+
+ process = new ProcessBuilder()
+ .command(args)
+ .redirectErrorStream(true)
+ .start();
+ }
+
+ public boolean isStarted() {
+ return process != null;
+ }
+
+ public Process getProcess() {
+ if (!isStarted()) {
+ throw new IllegalStateException("Not started!");
+ }
+
+ return process;
+ }
+
+ public synchronized List<String> gatherOutput()
+ throws IOException, InterruptedException {
+ if (!isStarted()) {
+ throw new IllegalStateException("Not started!");
+ }
+
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+ List<String> outputLines = new ArrayList<String>();
+ String outputLine;
+ while ((outputLine = in.readLine()) != null) {
+ outputLines.add(outputLine);
+ }
+
+ if (process.waitFor() != 0 && !permitNonZeroExitStatus) {
+ StringBuilder message = new StringBuilder();
+ for (String line : outputLines) {
+ message.append("\n").append(line);
+ }
+ throw new CommandFailedException(args, outputLines);
+ }
+
+ return outputLines;
+ }
+
+ public synchronized List<String> execute() {
+ try {
+ start();
+ return gatherOutput();
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to execute process: " + args, e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted while executing process: " + args, e);
+ }
+ }
+
+ static class Builder {
+ private final List<String> args = new ArrayList<String>();
+ private boolean permitNonZeroExitStatus = false;
+
+ public Builder args(String... args) {
+ return args(Arrays.asList(args));
+ }
+
+ public Builder args(Collection<String> args) {
+ this.args.addAll(args);
+ return this;
+ }
+
+ public Builder permitNonZeroExitStatus() {
+ permitNonZeroExitStatus = true;
+ return this;
+ }
+
+ public Command build() {
+ return new Command(this);
+ }
+
+ public List<String> execute() {
+ return build().execute();
+ }
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/CommandFailedException.java b/tools/dalvik_jtreg/java/dalvik/jtreg/CommandFailedException.java
new file mode 100644
index 0000000..ebbb42e
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/CommandFailedException.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import java.util.List;
+
+/**
+ * Thrown when an out of process executable does not return normally.
+ */
+class CommandFailedException extends RuntimeException {
+
+ private final List<String> args;
+ private final List<String> outputLines;
+
+ public CommandFailedException(List<String> args, List<String> outputLines) {
+ super("Command failed: " + args);
+ this.args = args;
+ this.outputLines = outputLines;
+ }
+
+ public List<String> getArgs() {
+ return args;
+ }
+
+ public List<String> getOutputLines() {
+ return outputLines;
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/Dx.java b/tools/dalvik_jtreg/java/dalvik/jtreg/Dx.java
new file mode 100644
index 0000000..21bcbbe
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/Dx.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import java.io.File;
+
+/**
+ * A dx command.
+ */
+final class Dx {
+
+ public void dex(String output, File... inputs) {
+ new Command.Builder()
+ .args("dx")
+ .args("--dex")
+ .args("--output=" + output)
+ .args(Strings.objectsToStrings(inputs))
+ .execute();
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/ExpectedResult.java b/tools/dalvik_jtreg/java/dalvik/jtreg/ExpectedResult.java
new file mode 100644
index 0000000..79ee36c
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/ExpectedResult.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * The expected outcome of a test execution. This is typically encoded in a
+ * properties file named by the test name and the {@code .expected} suffix; for
+ * example, {@code java.util.Arrays.CopyMethods.expected}.
+ */
+class ExpectedResult {
+
+ /**
+ * Property identifier for the test's expected result, such as {@code
+ * EXEC_FAILED}. This property is required.
+ */
+ static final String RESULT = "result";
+
+ /**
+ * Property identifier for a regular expression that is the expected output
+ * will match. This property is optional.
+ */
+ static final String PATTERN = "pattern";
+
+ /**
+ * The expectation of a general successful test run.
+ */
+ static final ExpectedResult SUCCESS = new ExpectedResult(
+ Result.SUCCESS, ".*");
+
+ private final Result result;
+ private final String pattern;
+
+ private ExpectedResult(File expectationFile) throws IOException {
+ Properties properties = new Properties();
+ FileInputStream in = new FileInputStream(expectationFile);
+ properties.load(in);
+ in.close();
+
+ result = Result.valueOf(properties.getProperty(RESULT));
+ pattern = properties.getProperty(PATTERN);
+ }
+
+ private ExpectedResult(Result result, String pattern) {
+ this.result = result;
+ this.pattern = pattern;
+ }
+
+ public Result getResult() {
+ return result;
+ }
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ public static ExpectedResult forRun(Set<File> searchDirectories,
+ String qualifiedName) throws IOException {
+ for (File expectationDir : searchDirectories) {
+ File expectationFile = new File(expectationDir, qualifiedName + ".expected");
+ if (expectationFile.exists()) {
+ return new ExpectedResult(expectationFile);
+ }
+ }
+
+ return SUCCESS;
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/Javac.java b/tools/dalvik_jtreg/java/dalvik/jtreg/Javac.java
new file mode 100644
index 0000000..0808200
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/Javac.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * A javac command.
+ */
+final class Javac {
+
+ private final Command.Builder builder = new Command.Builder();
+
+ Javac() {
+ builder.args("javac", "-Xmaxerrs", "1");
+ }
+
+ public Javac bootClasspath(File... path) {
+ builder.args("-bootclasspath", Command.path((Object[]) path));
+ return this;
+ }
+
+ public Javac classpath(File... path) {
+ builder.args("-classpath", Command.path((Object[]) path));
+ return this;
+ }
+
+ public Javac sourcepath(File... path) {
+ builder.args("-sourcepath", Command.path((Object[]) path));
+ return this;
+ }
+
+ public Javac destination(File directory) {
+ builder.args("-d", directory.toString());
+ return this;
+ }
+
+ public List<String> compile(File... files) {
+ return builder.args(Strings.objectsToStrings(files))
+ .execute();
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/JtregRunner.java b/tools/dalvik_jtreg/java/dalvik/jtreg/JtregRunner.java
new file mode 100644
index 0000000..bfe2908
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/JtregRunner.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import com.sun.javatest.TestDescription;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+/**
+ * Runs a directory's worth of jtreg tests on a device.
+ */
+public final class JtregRunner {
+
+ private static final Logger logger = Logger.getLogger(JtregRunner.class.getName());
+
+ private final File localTemp = new File("/tmp/" + UUID.randomUUID());
+ private final File deviceTemp = new File("/data/jtreg" + UUID.randomUUID());
+
+ private final Adb adb = new Adb();
+ private final File directoryToScan;
+ private final TestToDex testToDex;
+ private final ExecutorService outputReaders = Executors.newFixedThreadPool(1);
+
+ private Integer debugPort;
+ private Set<File> expectationDirs = new LinkedHashSet<File>();
+ private long timeoutSeconds = 10 * 60; // default is ten minutes
+ private File xmlReportsDirectory;
+
+ private File deviceTestRunner;
+
+ public JtregRunner(File sdkJar, File directoryToScan) {
+ this.directoryToScan = directoryToScan;
+ this.testToDex = new TestToDex(sdkJar, localTemp);
+ }
+
+ /**
+ * Builds and executes all tests in the test directory.
+ */
+ public void buildAndRunAllTests() throws Exception {
+ localTemp.mkdirs();
+
+ List<TestDescription> tests = testToDex.findTests(directoryToScan);
+ final BlockingQueue<TestRun> readyToRun = new ArrayBlockingQueue<TestRun>(4);
+
+ // build and install tests in a background thread. Using lots of
+ // threads helps for packages that contain many unsupported tests
+ ExecutorService builders = Executors.newFixedThreadPool(8);
+ for (final TestDescription testDescription : tests) {
+ builders.submit(new Callable<Void>() {
+ public Void call() throws Exception {
+ String qualifiedName = TestDescriptions.qualifiedName(testDescription);
+ ExpectedResult expectedResult = ExpectedResult.forRun(expectationDirs, qualifiedName);
+ TestRun testRun = new TestRun(qualifiedName, testDescription, expectedResult);
+ buildAndInstall(testRun);
+ readyToRun.put(testRun);
+ return null;
+ }
+ });
+ }
+ builders.shutdown();
+
+ prepareDevice();
+
+ int unsupportedTests = 0;
+
+ List<TestRun> runs = new ArrayList<TestRun>(tests.size());
+ while (!builders.isTerminated() || !readyToRun.isEmpty()) {
+ TestRun testRun = readyToRun.take();
+ runs.add(testRun);
+
+ if (testRun.getResult() == Result.UNSUPPORTED) {
+ logger.fine("skipping " + testRun.getQualifiedName());
+ unsupportedTests++;
+ continue;
+ }
+
+ if (testRun.isRunnable()) {
+ runTest(testRun);
+ }
+
+ printResult(testRun);
+ }
+
+ if (unsupportedTests > 0) {
+ logger.info("Skipped " + unsupportedTests + " unsupported tests.");
+ }
+
+ if (xmlReportsDirectory != null) {
+ logger.info("Printing XML Reports... ");
+ int numFiles = new XmlReportPrinter().generateReports(xmlReportsDirectory, runs);
+ logger.info(numFiles + " XML files written.");
+ }
+ }
+
+ /**
+ * Initializes the temporary directories and test harness necessary to run
+ * tests on a device.
+ */
+ private void prepareDevice() {
+ adb.mkdir(deviceTemp);
+ File testRunnerJar = testToDex.writeTestRunnerJar();
+ adb.push(testRunnerJar, deviceTemp);
+ deviceTestRunner = new File(deviceTemp, testRunnerJar.getName());
+ if (debugPort != null) {
+ adb.forwardTcp(debugPort, debugPort);
+ }
+ logger.info("Prepared device.");
+ }
+
+ /**
+ * Creates a dex file for the given test and push it out to the device.
+ *
+ * @return true if building and installing completed successfully.
+ */
+ private void buildAndInstall(TestRun testRun) {
+ TestDescription testDescription = testRun.getTestDescription();
+ String qualifiedName = testRun.getQualifiedName();
+ logger.fine("building " + testRun.getQualifiedName());
+
+ File base = new File(deviceTemp, qualifiedName);
+ adb.mkdir(base);
+
+ File dex;
+ try {
+ dex = testToDex.dexify(testDescription);
+ if (dex == null) {
+ testRun.setResult(Result.UNSUPPORTED, Collections.<String>emptyList());
+ return;
+ }
+ } catch (CommandFailedException e) {
+ testRun.setResult(Result.COMPILE_FAILED, e.getOutputLines());
+ return;
+ } catch (IOException e) {
+ testRun.setResult(Result.ERROR, e);
+ return;
+ }
+
+ logger.fine("installing " + testRun.getQualifiedName());
+ adb.push(testDescription.getDir(), base);
+ adb.push(dex, deviceTemp);
+ testRun.setInstalledFiles(base, new File(deviceTemp, dex.getName()));
+ }
+
+ /**
+ * Runs the specified test on the device.
+ */
+ private void runTest(TestRun testRun) {
+ if (!testRun.isRunnable()) {
+ throw new IllegalArgumentException();
+ }
+
+ Command.Builder builder = new Command.Builder();
+ builder.args("adb", "shell", "dalvikvm");
+ builder.args("-classpath", Command.path(testRun.getDeviceDex(), deviceTestRunner));
+ builder.args("-Duser.dir=" + testRun.getBase());
+ if (debugPort != null) {
+ builder.args("-Xrunjdwp:transport=dt_socket,address="
+ + debugPort + ",server=y,suspend=y");
+ }
+ builder.args("dalvik.jtreg.TestRunner");
+ final Command command = builder.build();
+
+ try {
+ command.start();
+
+ // run on a different thread to allow a timeout
+ List<String> output = outputReaders.submit(new Callable<List<String>>() {
+ public List<String> call() throws Exception {
+ return command.gatherOutput();
+ }
+ }).get(timeoutSeconds, TimeUnit.SECONDS);
+
+ if (output.isEmpty()) {
+ testRun.setResult(Result.ERROR,
+ Collections.singletonList("No output returned!"));
+ return;
+ }
+
+ Result result = "SUCCESS".equals(output.get(output.size() - 1))
+ ? Result.SUCCESS
+ : Result.EXEC_FAILED;
+ testRun.setResult(result, output.subList(0, output.size() - 1));
+ } catch (TimeoutException e) {
+ testRun.setResult(Result.EXEC_TIMEOUT, e);
+ } catch (Exception e) {
+ testRun.setResult(Result.ERROR,
+ Collections.singletonList("Exceeded timeout! (" + timeoutSeconds + "s)"));
+ } finally {
+ if (command.isStarted()) {
+ command.getProcess().destroy(); // to release the output reader
+ }
+ }
+ }
+
+ private void printResult(TestRun testRun) {
+ ExpectedResult expected = testRun.getExpectedResult();
+ boolean patternSuccess;
+
+ if (expected.getPattern() != null) {
+ Pattern pattern = Pattern.compile(expected.getPattern(),
+ Pattern.MULTILINE | Pattern.DOTALL);
+ patternSuccess = pattern.matcher(Strings.join(testRun.getOutputLines(), "\n")).matches();
+ } else {
+ patternSuccess = true;
+ }
+
+ if (expected.getResult() == testRun.getResult() && patternSuccess) {
+ logger.info("OK " + testRun.getQualifiedName() + " (" + testRun.getResult() + ")");
+ return;
+ }
+
+ logger.info("FAIL " + testRun.getQualifiedName() + " (" + testRun.getResult() + ")");
+ logger.info(" \"" + testRun.getTestDescription().getTitle() + "\"");
+
+ if (expected.getResult() != Result.SUCCESS
+ && expected.getResult() != testRun.getResult()) {
+ logger.info(" Expected result: " + expected.getResult());
+ }
+
+ if (!patternSuccess) {
+ logger.info(" Expected output to match \"" + expected.getPattern() + "\"");
+ }
+
+ for (String output : testRun.getOutputLines()) {
+ logger.info(" " + output);
+ }
+ }
+
+ private void shutdown() {
+ adb.rm(deviceTemp);
+ outputReaders.shutdown();
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 2) {
+ System.out.println("Usage: JTRegRunner [options]... <android jar> <tests directory>");
+ System.out.println();
+ System.out.println(" <android jar>: the API jar file to compile against. Usually");
+ System.out.println(" this is <SDK>/platforms/android-<X.X>/android.jar where");
+ System.out.println(" <SDK> is the path to an Android SDK path and <X.X> is a");
+ System.out.println(" release version like 1.5.");
+ System.out.println();
+ System.out.println(" <tests directory>: a directory to scan for test cases;");
+ System.out.println(" typically this is 'platform_v6/jdk/test' if 'platform_v6'");
+ System.out.println(" contains the sources of a platform implementation.");
+ System.out.println();
+ System.out.println("OPTIONS");
+ System.out.println();
+ System.out.println(" --debug <port>: enable Java debugging on the specified port.");
+ System.out.println(" This port must be free both on the device and on the local");
+ System.out.println(" system.");
+ System.out.println();
+ System.out.println(" --expectations <directory>: use the specified directory when");
+ System.out.println(" looking for test expectations. The directory should include");
+ System.out.println(" <test>.expected files describing expected results.");
+ System.out.println();
+ System.out.println(" --timeout-seconds <seconds>: maximum execution time of each");
+ System.out.println(" test before the runner aborts it.");
+ System.out.println();
+ System.out.println(" --xml-reports-directory <path>: directory to emit JUnit-style");
+ System.out.println(" XML test results.");
+ System.out.println();
+ System.out.println(" --verbose: turn on verbose output");
+ System.out.println();
+ return;
+ }
+
+ prepareLogging();
+
+ File sdkJar = new File(args[args.length - 2]);
+ if (!sdkJar.exists()) {
+ throw new RuntimeException("Could not find SDK jar: " + sdkJar);
+ }
+
+ File directoryToScan = new File(args[args.length - 1]);
+ if (!directoryToScan.isDirectory()) {
+ throw new RuntimeException("Invalid test directory: " + directoryToScan);
+ }
+
+ JtregRunner jtregRunner = new JtregRunner(sdkJar, directoryToScan);
+
+ for (int i = 0; i < args.length - 2; i++) {
+ if ("--debug".equals(args[i])) {
+ jtregRunner.debugPort = Integer.valueOf(args[++i]);
+
+ } else if ("--expectations".equals(args[i])) {
+ File expectationDir = new File(args[++i]);
+ if (!expectationDir.isDirectory()) {
+ throw new RuntimeException("Invalid expectation directory: " + directoryToScan);
+ }
+ jtregRunner.expectationDirs.add(expectationDir);
+
+ } else if ("--timeout-seconds".equals(args[i])) {
+ jtregRunner.timeoutSeconds = Long.valueOf(args[++i]);
+
+ } else if ("--verbose".equals(args[i])) {
+ Logger.getLogger("dalvik.jtreg").setLevel(Level.FINE);
+
+ } else if ("--xml-reports-directory".equals(args[i])) {
+ jtregRunner.xmlReportsDirectory = new File(args[++i]);
+ if (!jtregRunner.xmlReportsDirectory.isDirectory()) {
+ throw new RuntimeException("Invalid XML reports directory: "
+ + jtregRunner.xmlReportsDirectory);
+ }
+
+ } else {
+ throw new RuntimeException("Unrecognized option: " + args[i]);
+ }
+ }
+
+ jtregRunner.buildAndRunAllTests();
+ jtregRunner.shutdown();
+ }
+
+ private static void prepareLogging() {
+ ConsoleHandler handler = new ConsoleHandler();
+ handler.setLevel(Level.ALL);
+ handler.setFormatter(new Formatter() {
+ @Override public String format(LogRecord r) {
+ return r.getMessage() + "\n";
+ }
+ });
+ Logger logger = Logger.getLogger("dalvik.jtreg");
+ logger.addHandler(handler);
+ logger.setUseParentHandlers(false);
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/Result.java b/tools/dalvik_jtreg/java/dalvik/jtreg/Result.java
new file mode 100644
index 0000000..b612407
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/Result.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+/**
+ * A test run result.
+ */
+public enum Result {
+
+ /**
+ * A test that cannot be run by this harness, such as a shell script.
+ */
+ UNSUPPORTED,
+
+ COMPILE_FAILED,
+ EXEC_FAILED,
+ EXEC_TIMEOUT,
+ ERROR,
+ SUCCESS
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/Strings.java b/tools/dalvik_jtreg/java/dalvik/jtreg/Strings.java
new file mode 100644
index 0000000..c06c98a
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/Strings.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package dalvik.jtreg;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * Utility methods for strings.
+ */
+public class Strings {
+
+ static String join(Object[] objects, String delimiter) {
+ return join(Arrays.asList(objects), delimiter);
+ }
+
+ static String join(Iterable<?> objects, String delimiter) {
+ Iterator<?> i = objects.iterator();
+ if (!i.hasNext()) {
+ return "";
+ }
+
+ StringBuilder result = new StringBuilder();
+ result.append(i.next());
+ while(i.hasNext()) {
+ result.append(delimiter).append(i.next());
+ }
+ return result.toString();
+ }
+
+ static String[] objectsToStrings(Object[] objects) {
+ String[] result = new String[objects.length];
+ int i = 0;
+ for (Object o : objects) {
+ result[i++] = o.toString();
+ }
+ return result;
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/TestDescriptions.java b/tools/dalvik_jtreg/java/dalvik/jtreg/TestDescriptions.java
new file mode 100644
index 0000000..c7ffe7f
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/TestDescriptions.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import com.sun.javatest.TestDescription;
+
+import java.util.Properties;
+
+/**
+ * Utility methods for manipulating {@link TestDescription} instances.
+ */
+class TestDescriptions {
+
+ /**
+ * The subpath of a platform implementation under which tests live. Used to
+ * derive relative test paths like {@code /java/io/Reader} from an absolute
+ * path like {@code /home/jessewilson/platform_v6/test/java/io/Reader}.
+ */
+ static final String TEST_ROOT = "/test/";
+
+ /**
+ * Returns a properties object for the given test description.
+ */
+ static Properties toProperties(TestDescription testDescription) {
+ Properties result = new Properties();
+ result.setProperty(TestRunner.CLASS_NAME, testDescription.getName());
+ result.setProperty(TestRunner.QUALIFIED_NAME, qualifiedName(testDescription));
+ return result;
+ }
+
+ /**
+ * Returns a fully qualified name of the form {@code
+ * java.lang.Math.PowTests} from the given test description. The returned
+ * name is appropriate for use in a filename.
+ */
+ static String qualifiedName(TestDescription testDescription) {
+ return className(testDescription) + "." + escape(testDescription.getName());
+ }
+
+ /**
+ * Returns the name of the class under test, such as {@code java.lang.Math}.
+ */
+ static String className(TestDescription testDescription) {
+ String dir = testDescription.getDir().toString();
+ int separatorIndex = dir.indexOf(TEST_ROOT);
+ return separatorIndex != -1
+ ? escape(dir.substring(separatorIndex + TEST_ROOT.length()))
+ : escape(dir);
+ }
+
+ /**
+ * Returns a similar string with filename-unsafe characters replaced by
+ * filename-safe ones.
+ */
+ private static String escape(String s) {
+ return s.replace('/', '.');
+ }
+
+ private TestDescriptions() {}
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/TestRun.java b/tools/dalvik_jtreg/java/dalvik/jtreg/TestRun.java
new file mode 100644
index 0000000..feb919a
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/TestRun.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import com.sun.javatest.TestDescription;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A test run and its outcome.
+ */
+public final class TestRun {
+
+ private final TestDescription testDescription;
+ private final String qualifiedName;
+ private final ExpectedResult expectedResult;
+
+ private File base;
+ private File deviceDex;
+
+ private Result result;
+ private List<String> outputLines;
+
+
+ public TestRun(String qualifiedName, TestDescription testDescription,
+ ExpectedResult expectedResult) {
+ this.qualifiedName = qualifiedName;
+ this.testDescription = testDescription;
+ this.expectedResult = expectedResult;
+ }
+
+ public TestDescription getTestDescription() {
+ return testDescription;
+ }
+
+ public String getQualifiedName() {
+ return qualifiedName;
+ }
+
+ /**
+ * Initializes the on-device base directory from which the test program
+ * shall be executed, and the dex file containing that program.
+ */
+ public void setInstalledFiles(File base, File deviceDex) {
+ if (this.base != null) {
+ throw new IllegalStateException();
+ }
+
+ this.base = base;
+ this.deviceDex = deviceDex;
+ }
+
+ /**
+ * Returns true if this test is ready for execution on a device.
+ */
+ public boolean isRunnable() {
+ return base != null && deviceDex != null;
+ }
+
+ /**
+ * Returns the test's base directory, from which local files can be read by
+ * the test.
+ */
+ public File getBase() {
+ return base;
+ }
+
+ /**
+ * Returns the jar file containing the test code.
+ */
+ public File getDeviceDex() {
+ return deviceDex;
+ }
+
+ public void setResult(Result result, Throwable e) {
+ setResult(result, throwableToLines(e));
+ }
+
+ public void setResult(Result result, List<String> outputLines) {
+ if (this.result != null) {
+ throw new IllegalStateException();
+ }
+
+ this.result = result;
+ this.outputLines = outputLines;
+ }
+
+ private static List<String> throwableToLines(Throwable t) {
+ StringWriter writer = new StringWriter();
+ PrintWriter out = new PrintWriter(writer);
+ t.printStackTrace(out);
+ return Arrays.asList(writer.toString().split("\\n"));
+ }
+
+ public Result getResult() {
+ return result;
+ }
+
+ public List<String> getOutputLines() {
+ return outputLines;
+ }
+
+ public ExpectedResult getExpectedResult() {
+ return expectedResult;
+ }
+
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/TestRunner.java b/tools/dalvik_jtreg/java/dalvik/jtreg/TestRunner.java
new file mode 100644
index 0000000..f1b5577
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/TestRunner.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+/**
+ * Runs a jtreg test that was prepared with {@link TestToDex}.
+ */
+public final class TestRunner {
+
+ /**
+ * The name of the test properties file within the {@code .jar} file.
+ */
+ static final String TEST_PROPERTIES_FILE = "test.properties";
+
+ /**
+ * Property identifier for the test's main class name. This class should
+ * have a {@code public static void main(String[] args)} method.
+ */
+ static final String CLASS_NAME = "className";
+
+ /**
+ * Property identifier for the test's name, such as {@code
+ * java.math.BigDecimal.PowTests}.
+ */
+ static final String QUALIFIED_NAME = "qualifiedName";
+
+ private String className;
+ private String qualifiedName;
+
+ private Method main;
+
+ public void test(String[] args)
+ throws InvocationTargetException, IllegalAccessException {
+ System.out.println("Executing " + qualifiedName);
+ try {
+ main.invoke(null, new Object[] { args });
+ System.out.println("SUCCESS");
+ } catch (Throwable failure) {
+ failure.printStackTrace();
+ System.out.println("FAILURE");
+ }
+ }
+
+ private void loadProperties() {
+ Properties properties = new Properties();
+ try {
+ InputStream propertiesStream = TestRunner.class.getResourceAsStream(
+ "/" + TEST_PROPERTIES_FILE);
+ if (propertiesStream == null) {
+ throw new RuntimeException(TEST_PROPERTIES_FILE + " missing!");
+ }
+
+ properties.load(propertiesStream);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ className = properties.getProperty(CLASS_NAME);
+ qualifiedName = properties.getProperty(QUALIFIED_NAME);
+
+ if (className == null || qualifiedName == null) {
+ throw new RuntimeException(TEST_PROPERTIES_FILE + " missing required values!");
+ }
+ }
+
+ private void prepareTest() {
+ try {
+ Class<?> testClass = Class.forName(className);
+ main = testClass.getMethod("main", String[].class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ // Usage: TestRunner [optional test args]...
+
+ TestRunner testRunner = new TestRunner();
+ testRunner.loadProperties();
+ testRunner.prepareTest();
+ testRunner.test(args);
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/TestToDex.java b/tools/dalvik_jtreg/java/dalvik/jtreg/TestToDex.java
new file mode 100644
index 0000000..6badf34
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/TestToDex.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import com.sun.javatest.TestDescription;
+import com.sun.javatest.TestResult;
+import com.sun.javatest.TestResultTable;
+import com.sun.javatest.TestSuite;
+import com.sun.javatest.WorkDirectory;
+import com.sun.javatest.regtest.RegressionTestSuite;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+/**
+ * Scans a directory of jtreg tests and creates Dalvik-friendly {@code .jar}
+ * files for them. These tests can be executed by {@link TestRunner}. Because of
+ * the heavy use of the default package by jtreg tests, it is not generally
+ * possible to run multiple tests in the same dalvik VM.
+ */
+final class TestToDex {
+
+ private static final String DALVIK_JTREG_HOME
+ = "dalvik/libcore/tools/dalvik_jtreg";
+ private static final File JTREG_JAR
+ = new File(DALVIK_JTREG_HOME + "/lib/jtreg.jar");
+ private static final File TEST_RUNNER_JAVA
+ = new File(DALVIK_JTREG_HOME + "/java/dalvik/jtreg/TestRunner.java");
+
+ private static final Logger logger = Logger.getLogger(TestToDex.class.getName());
+
+ private final Pattern JAVA_TEST_PATTERN = Pattern.compile("\\/(\\w)+\\.java$");
+
+ private final File sdkJar;
+ private final File temp;
+
+ TestToDex(File sdkJar, File temp) {
+ this.sdkJar = sdkJar;
+ this.temp = temp;
+ }
+
+ /**
+ * Creates a testrunner jar that can execute the packaged tests.
+ */
+ File writeTestRunnerJar() {
+ File base = new File(temp, "testrunner");
+ base.mkdirs();
+
+ new Javac()
+ .destination(base)
+ .compile(TEST_RUNNER_JAVA);
+
+ File output = new File(temp, "testrunner.jar");
+ new Dx().dex(output.toString(), base);
+ return output;
+ }
+
+ /**
+ * Writes a Dalvik-friendly {@code .jar} for the described test.
+ *
+ * @return the path of the constructed {@code .jar}, or {@code null} if the
+ * test cannot be converted to Dex (presumably because it is not of
+ * the right type).
+ * @throws CommandFailedException if javac fails
+ */
+ File dexify(TestDescription testDescription) throws IOException {
+ String qualifiedName = TestDescriptions.qualifiedName(testDescription);
+
+ if (!JAVA_TEST_PATTERN.matcher(testDescription.getFile().toString()).find()) {
+ return null;
+ }
+
+ File jarContents = new File(temp, qualifiedName);
+ jarContents.mkdirs();
+
+ // write a test descriptor
+ Properties properties = TestDescriptions.toProperties(testDescription);
+ FileOutputStream propertiesOut = new FileOutputStream(
+ new File(jarContents, TestRunner.TEST_PROPERTIES_FILE));
+ properties.store(propertiesOut, "generated by " + getClass().getName());
+ propertiesOut.close();
+
+ new Javac()
+ .bootClasspath(sdkJar)
+ .classpath(testDescription.getDir(), JTREG_JAR)
+ .sourcepath(testDescription.getDir())
+ .destination(jarContents)
+ .compile(testDescription.getFile());
+
+ File output = new File(temp, qualifiedName + ".jar");
+ new Dx().dex(output.toString(), jarContents);
+ return output;
+ }
+
+ /**
+ * Scans {@code directoryToScan} for test cases, using JTHarness + jtreg
+ * behind the scenes.
+ */
+ List<TestDescription> findTests(File directoryToScan) throws Exception {
+ logger.info("Scanning " + directoryToScan + " for tests.");
+ File workDirectory = new File(temp, "JTwork");
+ workDirectory.mkdirs();
+
+ /*
+ * This code is capable of extracting test descriptions using jtreg 4.0
+ * and its bundled copy of jtharness. As a command line tool, jtreg's
+ * API wasn't intended for this style of use. As a consequence, this
+ * code is fragile and may be incompatible with newer versions of jtreg.
+ */
+ TestSuite testSuite = new RegressionTestSuite(directoryToScan);
+ WorkDirectory wd = WorkDirectory.convert(workDirectory, testSuite);
+ TestResultTable resultTable = wd.getTestResultTable();
+
+ List<TestDescription> result = new ArrayList<TestDescription>();
+ for (Iterator i = resultTable.getIterator(); i.hasNext(); ) {
+ TestResult testResult = (TestResult) i.next();
+ result.add(testResult.getDescription());
+ }
+ logger.info("Found " + result.size() + " tests.");
+ return result;
+ }
+}
diff --git a/tools/dalvik_jtreg/java/dalvik/jtreg/XmlReportPrinter.java b/tools/dalvik_jtreg/java/dalvik/jtreg/XmlReportPrinter.java
new file mode 100644
index 0000000..bfea0bc
--- /dev/null
+++ b/tools/dalvik_jtreg/java/dalvik/jtreg/XmlReportPrinter.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.jtreg;
+
+import org.kxml2.io.KXmlSerializer;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+
+/**
+ * Writes JUnit results to a series of XML files in a format consistent with
+ * Ant's XMLJUnitResultFormatter.
+ *
+ * <p>Unlike Ant's formatter, this class does not report the execution time of
+ * tests.
+ *
+ * TODO: unify this and com.google.coretests.XmlReportPrinter
+ */
+public class XmlReportPrinter {
+
+ /**
+ * Test results of these types are omitted from the report, as if the tests
+ * never existed. Equivalent to the core test runner's @BrokenTest.
+ */
+ private static final EnumSet<Result> IGNORED_RESULTS
+ = EnumSet.of(Result.COMPILE_FAILED);
+
+ private static final EnumSet<Result> FAILED_RESULTS
+ = EnumSet.of(Result.EXEC_FAILED);
+ private static final EnumSet<Result> ERROR_RESULTS
+ = EnumSet.complementOf(EnumSet.of(Result.EXEC_FAILED, Result.SUCCESS));
+
+ private static final String TESTSUITE = "testsuite";
+ private static final String TESTCASE = "testcase";
+ private static final String ERROR = "error";
+ private static final String FAILURE = "failure";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_TIME = "time";
+ private static final String ATTR_ERRORS = "errors";
+ private static final String ATTR_FAILURES = "failures";
+ private static final String ATTR_TESTS = "tests";
+ private static final String ATTR_TYPE = "type";
+ private static final String ATTR_MESSAGE = "message";
+ private static final String PROPERTIES = "properties";
+ private static final String ATTR_CLASSNAME = "classname";
+ private static final String TIMESTAMP = "timestamp";
+ private static final String HOSTNAME = "hostname";
+
+ /** the XML namespace */
+ private static final String ns = null;
+
+ /**
+ * Populates the directory with the report data from the completed tests.
+ */
+ public int generateReports(File directory, Collection<TestRun> results) {
+ Map<String, Suite> suites = testsToSuites(results);
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ TimeZone gmt = TimeZone.getTimeZone("GMT");
+ dateFormat.setTimeZone(gmt);
+ dateFormat.setLenient(true);
+ String timestamp = dateFormat.format(new Date());
+
+ for (Suite suite : suites.values()) {
+ FileOutputStream stream = null;
+ try {
+ stream = new FileOutputStream(new File(directory, "TEST-" + suite.name + ".xml"));
+
+ KXmlSerializer serializer = new KXmlSerializer();
+ serializer.setOutput(stream, "UTF-8");
+ serializer.startDocument("UTF-8", null);
+ serializer.setFeature(
+ "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ suite.print(serializer, timestamp);
+ serializer.endDocument();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ }
+
+ return suites.size();
+ }
+
+ private Map<String, Suite> testsToSuites(Collection<TestRun> testRuns) {
+ Map<String, Suite> result = new LinkedHashMap<String, Suite>();
+ for (TestRun testRun : testRuns) {
+ if (IGNORED_RESULTS.contains(testRun.getResult())) {
+ continue;
+ }
+
+ String suiteName = suiteName(testRun);
+ Suite suite = result.get(suiteName);
+ if (suite == null) {
+ suite = new Suite(suiteName);
+ result.put(suiteName, suite);
+ }
+
+ suite.tests.add(testRun);
+ if (FAILED_RESULTS.contains(testRun.getResult())) {
+ suite.failuresCount++;
+ } else if (ERROR_RESULTS.contains(testRun.getResult())) {
+ suite.errorsCount++;
+ }
+ }
+ return result;
+ }
+
+ private static String suiteName(TestRun testRun) {
+ return TestDescriptions.className(testRun.getTestDescription());
+ }
+
+ static class Suite {
+ private final String name;
+ private final List<TestRun> tests = new ArrayList<TestRun>();
+ private int failuresCount;
+ private int errorsCount;
+
+ Suite(String name) {
+ this.name = name;
+ }
+
+ void print(KXmlSerializer serializer, String timestamp) throws IOException {
+ serializer.startTag(ns, TESTSUITE);
+ serializer.attribute(ns, ATTR_NAME, name);
+ serializer.attribute(ns, ATTR_TESTS, Integer.toString(tests.size()));
+ serializer.attribute(ns, ATTR_FAILURES, Integer.toString(failuresCount));
+ serializer.attribute(ns, ATTR_ERRORS, Integer.toString(errorsCount));
+ serializer.attribute(ns, ATTR_TIME, "0");
+ serializer.attribute(ns, TIMESTAMP, timestamp);
+ serializer.attribute(ns, HOSTNAME, "localhost");
+ serializer.startTag(ns, PROPERTIES);
+ serializer.endTag(ns, PROPERTIES);
+
+ for (TestRun testRun : tests) {
+ print(serializer, testRun);
+ }
+
+ serializer.endTag(ns, TESTSUITE);
+ }
+
+ void print(KXmlSerializer serializer, TestRun testRun) throws IOException {
+ serializer.startTag(ns, TESTCASE);
+ serializer.attribute(ns, ATTR_NAME, testRun.getTestDescription().getName());
+ serializer.attribute(ns, ATTR_CLASSNAME, suiteName(testRun));
+ serializer.attribute(ns, ATTR_TIME, "0");
+
+ String result = ERROR_RESULTS.contains(testRun.getResult()) ? ERROR
+ : FAILED_RESULTS.contains(testRun.getResult()) ? FAILURE
+ : null;
+
+ if (result != null) {
+ serializer.startTag(ns, result);
+ String title = testRun.getTestDescription().getTitle();
+ if (title != null && title.length() > 0) {
+ serializer.attribute(ns, ATTR_MESSAGE, title);
+ }
+ serializer.attribute(ns, ATTR_TYPE, testRun.getResult().toString());
+ String text = sanitize(Strings.join(testRun.getOutputLines(), "\n"));
+ serializer.text(text);
+ serializer.endTag(ns, result);
+ }
+
+ serializer.endTag(ns, TESTCASE);
+ }
+
+ /**
+ * Returns the text in a format that is safe for use in an XML document.
+ */
+ private String sanitize(String text) {
+ return text.replace("\0", "<\\0>");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/dalvik_jtreg/lib/javatest.jar b/tools/dalvik_jtreg/lib/javatest.jar
new file mode 100644
index 0000000..f550f44
--- /dev/null
+++ b/tools/dalvik_jtreg/lib/javatest.jar
Binary files differ
diff --git a/tools/dalvik_jtreg/lib/jh.jar b/tools/dalvik_jtreg/lib/jh.jar
new file mode 100644
index 0000000..e5748fb
--- /dev/null
+++ b/tools/dalvik_jtreg/lib/jh.jar
Binary files differ
diff --git a/tools/dalvik_jtreg/lib/jtreg.jar b/tools/dalvik_jtreg/lib/jtreg.jar
new file mode 100644
index 0000000..452453a
--- /dev/null
+++ b/tools/dalvik_jtreg/lib/jtreg.jar
Binary files differ
diff --git a/tools/integrate/Android.mk b/tools/integrate/Android.mk
index 629a5fd..f0f25b3 100644
--- a/tools/integrate/Android.mk
+++ b/tools/integrate/Android.mk
@@ -7,9 +7,9 @@
Filesystem.java \
Git.java \
Module.java \
- Modules.java \
MappedDirectory.java \
PullHarmonyCode.java \
+ PushAndroidCode.java \
Svn.java
LOCAL_MODULE:= integrate
diff --git a/tools/integrate/Filesystem.java b/tools/integrate/Filesystem.java
index a9c1789..4b296a0 100644
--- a/tools/integrate/Filesystem.java
+++ b/tools/integrate/Filesystem.java
@@ -32,11 +32,28 @@
* directory is nonempty.
*/
public int moveContents(String source, String target) {
+ return copyContents(true, source, target);
+ }
+
+ /**
+ * Copies all of the files in {@code source} to {@code target}, one at a
+ * time. Unlike {@code move}, this approach works even if the target
+ * directory is nonempty.
+ */
+ public int copyContents(String source, String target) {
+ return copyContents(false, source, target);
+ }
+
+ private int copyContents(boolean move, String source, String target) {
List<String> files = new Command("find", source, "-type", "f") .execute();
for (String file : files) {
String targetFile = target + "/" + file.substring(source.length());
mkdir(parent(targetFile));
- new Command("mv", "-i", file, targetFile).execute();
+ if (move) {
+ new Command("mv", "-i", file, targetFile).execute();
+ } else {
+ new Command("cp", file, targetFile).execute();
+ }
}
return files.size();
}
diff --git a/tools/integrate/Module.java b/tools/integrate/Module.java
index 5cb7035..02cdb6a 100644
--- a/tools/integrate/Module.java
+++ b/tools/integrate/Module.java
@@ -14,7 +14,10 @@
* limitations under the License.
*/
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.Map;
import java.util.Set;
/**
@@ -22,6 +25,49 @@
*/
class Module {
+ static final Map<String, Module> VALUES;
+ static {
+ Map<String, Module> valuesMutable = new LinkedHashMap<String, Module>();
+
+ String svnRoot = "http://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules";
+ valuesMutable.put("archive", new Module.Builder(svnRoot, "archive")
+ .mapDirectory("archive/src/main/native/archive/shared",
+ "archive/src/main/native")
+ .mapDirectory("archive/src/main/native/zip/shared",
+ "archive/src/main/native")
+ .build());
+
+ valuesMutable.put("crypto", new Module.Builder(svnRoot, "crypto")
+ .mapDirectory("crypto/src/test/api/java.injected/javax",
+ "crypto/src/test/java/org/apache/harmony/crypto/tests/javax")
+ .mapDirectory("crypto/src/test/api/java",
+ "crypto/src/test/java")
+ .mapDirectory("crypto/src/test/resources/serialization",
+ "crypto/src/test/java/serialization")
+ .mapDirectory("crypto/src/test/support/common/java",
+ "crypto/src/test/java")
+ .build());
+
+ valuesMutable.put("logging", new Module.Builder(svnRoot, "logging").build());
+
+ valuesMutable.put("regex", new Module.Builder(svnRoot, "regex").build());
+
+ valuesMutable.put("security", new Module.Builder(svnRoot, "security")
+ .mapDirectory("security/src/main/java/common",
+ "security/src/main/java")
+ .mapDirectory("security/src/main/java/unix/org",
+ "security/src/main/java/org")
+ .mapDirectory("security/src/test/api/java",
+ "security/src/test/java")
+ .build());
+
+ valuesMutable.put("text", new Module.Builder(svnRoot, "text").build());
+
+ valuesMutable.put("x-net", new Module.Builder(svnRoot, "x-net").build());
+
+ VALUES = Collections.unmodifiableMap(valuesMutable);
+ }
+
private final String svnBaseUrl;
private final String path;
private final Set<MappedDirectory> mappedDirectories;
diff --git a/tools/integrate/Modules.java b/tools/integrate/Modules.java
deleted file mode 100644
index 2475852..0000000
--- a/tools/integrate/Modules.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Constants that define modules shared by Harmony and Dalvik.
- */
-public class Modules {
-
- private static final String SVN_ROOT
- = "http://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules";
-
- public static final Module ARCHIVE = new Module.Builder(SVN_ROOT, "archive")
- .mapDirectory("archive/src/main/native/archive/shared",
- "archive/src/main/native")
- .mapDirectory("archive/src/main/native/zip/shared",
- "archive/src/main/native")
- .build();
-
- public static final Module CRYPTO = new Module.Builder(SVN_ROOT, "crypto")
- .mapDirectory("crypto/src/test/api/java.injected/javax",
- "crypto/src/test/java/org/apache/harmony/crypto/tests/javax")
- .mapDirectory("crypto/src/test/api/java",
- "crypto/src/test/java")
- .mapDirectory("crypto/src/test/resources/serialization",
- "crypto/src/test/java/serialization")
- .mapDirectory("crypto/src/test/support/common/java",
- "crypto/src/test/java")
- .build();
-
- public static final Module REGEX
- = new Module.Builder(SVN_ROOT, "regex").build();
-
- public static final Module SECURITY = new Module.Builder(SVN_ROOT, "security")
- .mapDirectory("security/src/main/java/common",
- "security/src/main/java")
- .mapDirectory("security/src/main/java/unix/org",
- "security/src/main/java/org")
- .mapDirectory("security/src/test/api/java",
- "security/src/test/java")
- .build();
-
- public static final Module TEXT
- = new Module.Builder(SVN_ROOT, "text").build();
-
- public static final Module X_NET
- = new Module.Builder(SVN_ROOT, "x-net").build();
-
- // TODO: add the other modules
-}
diff --git a/tools/integrate/PullHarmonyCode.java b/tools/integrate/PullHarmonyCode.java
index 6710801..ce019d4 100644
--- a/tools/integrate/PullHarmonyCode.java
+++ b/tools/integrate/PullHarmonyCode.java
@@ -102,8 +102,61 @@
}
}
+
public static void main(String[] args) {
-// new PullHarmonyCode(527399, 802921).pull(Modules.CRYPTO);
- new PullHarmonyCode(772995, 802921).pull(Modules.ARCHIVE);
+ if (args.length < 3) {
+ printUsage();
+ return;
+ }
+
+ int currentSvnRev = Integer.parseInt(args[0]);
+ int targetSvnRev = Integer.parseInt(args[1]);
+
+ if (currentSvnRev < 527399 || targetSvnRev <= currentSvnRev) {
+ System.out.println("Invalid SVN revision range: "
+ + currentSvnRev + ".." + targetSvnRev);
+ return;
+ }
+
+ Module module = Module.VALUES.get(args[2]);
+ if (module == null) {
+ System.out.println("No such module: " + args[2]);
+ return;
+ }
+
+ PullHarmonyCode puller = new PullHarmonyCode(currentSvnRev, targetSvnRev);
+ puller.pull(module);
+ }
+
+ private static void printUsage() {
+ System.out.println("This tool will prepare a three-way merge between the latest Harmony");
+ System.out.println("the latest Dalvik, and their common ancestor. It downloads both old");
+ System.out.println("and new versions of Harmony code from SVN for better merge results.");
+ System.out.println();
+ System.out.println("Usage: PullHarmonyCode <current_rev> <target_rev> <module>...");
+ System.out.println();
+ System.out.println(" <current_rev> is the SVN revision of the Harmony code that was");
+ System.out.println(" most recently integrated into Dalvik. This should");
+ System.out.println(" be a number greater than 527399. The current");
+ System.out.println(" revision for each module is tracked at");
+ System.out.println(" http://go/dalvik/harmony");
+ System.out.println();
+ System.out.println(" <target_rev> is the SVN revision of the Harmony code to be");
+ System.out.println(" merged into Dalvik. This should be a number greater");
+ System.out.println(" than <current_rev>. The latest Harmony revision is");
+ System.out.println(" tracked at");
+ System.out.println(" http://svn.apache.org/viewvc/harmony/?root=Apache-SVN");
+ System.out.println();
+ System.out.println(" <module> is one of " + Module.VALUES.keySet());
+ System.out.println();
+ System.out.println("This program must be executed from within the dalvik/libcore directory");
+ System.out.println("of an Android git client. Such a client must be synced and contain no");
+ System.out.println("uncommitted changes. Upon termination, a new Git branch with the");
+ System.out.println("integrated changes will be active. This branch may require some manual");
+ System.out.println("merging.");
+ System.out.println();
+ System.out.println("Example usage:");
+ System.out.println(" java -cp ../../out/host/linux-x86/framework/integrate.jar PullAndroidCode \\");
+ System.out.println(" 527399 802921 security");
}
}
diff --git a/tools/integrate/PushAndroidCode.java b/tools/integrate/PushAndroidCode.java
new file mode 100644
index 0000000..c0002f5
--- /dev/null
+++ b/tools/integrate/PushAndroidCode.java
@@ -0,0 +1,87 @@
+// Copyright 2009 Google Inc. All Rights Reserved.
+
+import java.util.UUID;
+
+/**
+ * Copy the current Android sourcecode into Apache Harmony, where it can be
+ * reviewed and submitted to their SVN. Only run this script after first merging
+ * the latest harmony code into Android.
+ */
+public class PushAndroidCode {
+
+ private final String androidPath;
+ private final String harmonyPath;
+
+ public PushAndroidCode(String androidPath, String harmonyPath) {
+ this.androidPath = androidPath;
+ this.harmonyPath = harmonyPath;
+ }
+
+ public void push(Module module) {
+ Filesystem filesystem = new Filesystem();
+
+ // copy android code to a temp directory that is laid out like Harmony
+ String temp = "/tmp/" + UUID.randomUUID();
+ filesystem.mkdir(temp);
+ filesystem.copyContents(androidPath + "/" + module.path(),
+ temp + "/" + module.path());
+ for (MappedDirectory mappedDirectory : module.getMappedDirectories()) {
+ filesystem.moveContents(
+ temp + "/" + mappedDirectory.gitPath(),
+ temp + "/" + mappedDirectory.svnPath());
+ }
+
+ // clobber files from harmony with their Android equivalents
+ filesystem.copyContents(temp + "/" + module.path(),
+ harmonyPath + "/" + module.path());
+ }
+
+ public static void main(String[] args) {
+ if (args.length < 3) {
+ printUsage();
+ return;
+ }
+
+ String androidPath = args[0] + "/dalvik/libcore";
+ String harmonyPath = args[1] + "/working_classlib/modules";
+
+ // TODO: validate directories?
+
+ Module[] modules = new Module[args.length - 2];
+ for (int i = 0; i < modules.length; i++) {
+ modules[i] = Module.VALUES.get(args[i+2]);
+ if (modules[i] == null) {
+ System.out.println("No such module: " + args[i+2]);
+ return;
+ }
+ }
+
+ PushAndroidCode pusher = new PushAndroidCode(androidPath, harmonyPath);
+ for (Module module : modules) {
+ pusher.push(module);
+ }
+ }
+
+ private static void printUsage() {
+ System.out.println("This tool will clobber Harmony's core libraries with Android's copy");
+ System.out.println("so that a patch can be submitted upstream.");
+ System.out.println();
+ System.out.println("Usage: PushAndroidCode <android_root> <harmony_root> <module>...");
+ System.out.println();
+ System.out.println(" <android_root> is the android git client directory that contains dalvik");
+ System.out.println(" This should hold an up-to-date checkout of Android. The");
+ System.out.println(" target modules should also be up-to-date with respect to");
+ System.out.println(" Harmony; use the PullHarmonyCode tool first if necessary.");
+ System.out.println();
+ System.out.println(" <harmony_root> is the android client directory that contains working_classlib.");
+ System.out.println(" This should hold an up-to-date checkout of Harmony.");
+ System.out.println();
+ System.out.println(" <module> is one of " + Module.VALUES.keySet());
+ System.out.println();
+ System.out.println("Example usage:");
+ System.out.println(" java -cp out/host/linux-x86/framework/integrate.jar PushAndroidCode \\");
+ System.out.println(" /usr/local/google/jesse/clients/jessewilson_g1 \\");
+ System.out.println(" /usr/local/google/jesse/clients/jessewilson_h0/trunk \\");
+ System.out.println(" crypto");
+ }
+}
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
index 36282e1..d52f08f 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
@@ -196,28 +196,9 @@
return nativegetsupportedciphersuites();
}
- /**
- * Calls native OpenSSL functions to get the enabled ciphers.
- */
- private native String[] nativegetenabledciphersuites();
-
@Override
public String[] getEnabledCipherSuites() {
- return nativegetenabledciphersuites();
- }
-
- /**
- * Calls the SSL_CTX_set_cipher_list(...) OpenSSL function with the passed
- * char array.
- */
- private native void nativesetenabledciphersuites(String controlString);
-
- private boolean findSuite(String suite) {
- String[] supportedCipherSuites = nativegetsupportedciphersuites();
- for(int i = 0; i < supportedCipherSuites.length; i++)
- if (supportedCipherSuites[i].equals(suite)) return true;
- throw new IllegalArgumentException("Protocol " + suite +
- " is not supported.");
+ return OpenSSLSocketImpl.nativeGetEnabledCipherSuites(ssl_ctx);
}
/**
@@ -230,16 +211,7 @@
*/
@Override
public void setEnabledCipherSuites(String[] suites) {
- if (suites == null) {
- throw new IllegalArgumentException("Provided parameter is null");
- }
- String controlString = "";
- for (int i = 0; i < suites.length; i++) {
- findSuite(suites[i]);
- if (i == 0) controlString = suites[i];
- else controlString += ":" + suites[i];
- }
- nativesetenabledciphersuites(controlString);
+ OpenSSLSocketImpl.setEnabledCipherSuites(ssl_ctx, suites);
}
/**
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
index fcc1a77..d287bbd 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
@@ -662,7 +662,7 @@
return nativegetsupportedciphersuites();
}
- private native String[] nativegetenabledciphersuites();
+ static native String[] nativeGetEnabledCipherSuites(int ssl_ctx);
/**
* The names of the cipher suites that are in use in the actual the SSL
@@ -671,21 +671,23 @@
* @return an array of cipher suite names
*/
public String[] getEnabledCipherSuites() {
- return nativegetenabledciphersuites();
+ return nativeGetEnabledCipherSuites(ssl_ctx);
}
/**
* Calls the SSL_CTX_set_cipher_list(...) OpenSSL function with the passed
* char array.
*/
- private native void nativesetenabledciphersuites(String controlString);
+ static native void nativeSetEnabledCipherSuites(int ssl_ctx, String controlString);
- private boolean findSuite(String suite) {
+ private static boolean findSuite(String suite) {
String[] supportedCipherSuites = nativegetsupportedciphersuites();
- for(int i = 0; i < supportedCipherSuites.length; i++)
- if (supportedCipherSuites[i].equals(suite)) return true;
- throw new IllegalArgumentException("Protocol " + suite +
- " is not supported.");
+ for(int i = 0; i < supportedCipherSuites.length; i++) {
+ if (supportedCipherSuites[i].equals(suite)) {
+ return true;
+ }
+ }
+ throw new IllegalArgumentException("Protocol " + suite + " is not supported.");
}
/**
@@ -699,16 +701,20 @@
* is null.
*/
public void setEnabledCipherSuites(String[] suites) {
+ setEnabledCipherSuites(ssl_ctx, suites);
+ }
+
+ static void setEnabledCipherSuites(int ssl_ctx, String[] suites) {
if (suites == null) {
throw new IllegalArgumentException("Provided parameter is null");
}
String controlString = "";
- for(int i = 0; i < suites.length; i++) {
+ for (int i = 0; i < suites.length; i++) {
findSuite(suites[i]);
if (i == 0) controlString = suites[i];
else controlString += ":" + suites[i];
}
- nativesetenabledciphersuites(controlString);
+ nativeSetEnabledCipherSuites(ssl_ctx, controlString);
}
/**
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLInputStream.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLInputStream.java
index 6c23a91..507e14f 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLInputStream.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLInputStream.java
@@ -94,10 +94,11 @@
* Reads and returns uint64 value.
*/
public long readUint64() throws IOException {
- return (read() << 56) | (read() << 48)
- | (read() << 40) | (read() << 32)
- | (read() << 24) | (read() << 16)
- | (read() << 8) | (read() & 0x00FF);
+ // BEGIN android-changed
+ long hi = readUint32();
+ long lo = readUint32();
+ return (hi << 32) | lo;
+ // END android-changed
}
/**
@@ -131,4 +132,3 @@
return i;
}
}
-
diff --git a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl.cpp b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl.cpp
index 13a1e61..1e73041 100644
--- a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl.cpp
+++ b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl.cpp
@@ -41,20 +41,10 @@
static jfieldID field_ssl_ctx;
/**
- * Throws java.io.IOexception with the provided message.
+ * Throws java.io.IOException with the provided message.
*/
-static void throwIOExceptionStr(JNIEnv* env, const char* message)
-{
- jclass exClass = env->FindClass("java/io/IOException");
-
- if (exClass == NULL)
- {
- LOGE("Unable to find class java/io/IOException");
- }
- else
- {
- env->ThrowNew(exClass, message);
- }
+static void throwIOExceptionStr(JNIEnv* env, const char* message) {
+ jniThrowException(env, "java/io/IOException", message);
}
/**
@@ -87,9 +77,9 @@
// 'seed == null' when no SecureRandom Object is set
// in the SSLContext.
if (seed != NULL) {
- jboolean iscopy = JNI_FALSE;
- jbyte* randseed = env->GetByteArrayElements(seed, &iscopy);
+ jbyte* randseed = env->GetByteArrayElements(seed, NULL);
RAND_seed((unsigned char*) randseed, 1024);
+ env->ReleaseByteArrayElements(seed, randseed, 0);
} else {
RAND_load_file("/dev/urandom", 1024);
}
@@ -167,93 +157,13 @@
static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getsupportedciphersuites(JNIEnv* env,
jobject object)
{
- SSL_CTX* ctx;
- SSL* ssl;
- STACK_OF(SSL_CIPHER) *sk;
- jobjectArray ret;
- int i;
- const char *c;
-
- ctx = SSL_CTX_new(SSLv23_server_method());
- ssl = SSL_new(ctx);
- sk=SSL_get_ciphers(ssl);
-
- ret= (jobjectArray)env->NewObjectArray(5,
- env->FindClass("java/lang/String"),
- env->NewStringUTF(""));
-
- i = 0;
- while (SSL_get_cipher_list(ssl,i) != NULL) {
- i++;
+ SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+ if (ssl_ctx == NULL) {
+ return NULL;
}
-
- ret = (jobjectArray)env->NewObjectArray(i,
- env->FindClass("java/lang/String"),
- env->NewStringUTF(""));
-
- for (i=0; ; i++) {
- c=SSL_get_cipher_list(ssl,i);
- if (c == NULL) break;
-
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(c));
- }
-
- return ret;
-}
-
-/**
- * Loads the ciphers suites that are enabled in the OpenSSL server
- * and returns them in a string array.
- */
-static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getenabledciphersuites(JNIEnv* env,
- jobject object)
-{
- SSL_CTX* ctx;
- SSL* ssl;
- jobjectArray ret;
- int i;
- const char *c;
-
- ctx = (SSL_CTX*)env->GetIntField(object, field_ssl_ctx);
- ssl = SSL_new(ctx);
-
- i = 0;
- while (SSL_get_cipher_list(ssl,i) != NULL) {
- i++;
- }
-
- ret = (jobjectArray)env->NewObjectArray(i,
- env->FindClass("java/lang/String"),
- env->NewStringUTF(""));
-
- for (i = 0; ; i++) {
- c = SSL_get_cipher_list(ssl,i);
- if (c == NULL) break;
-
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(c));
- }
-
- return ret;
-}
-
-/**
- * Sets the ciphers suites that are enabled in the OpenSSL server.
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_setenabledciphersuites(JNIEnv* env,
- jobject object, jstring controlstring)
-{
- SSL_CTX* ctx;
- const char *str;
- int ret;
-
- ctx = (SSL_CTX*)env->GetIntField(object, field_ssl_ctx);
- str = env->GetStringUTFChars(controlstring, 0);
- ret = SSL_CTX_set_cipher_list(ctx, str);
-
- if(ret == 0) {
- jclass exClass = env->FindClass("java/lang/IllegalArgumentException");
- env->ThrowNew(exClass, "Illegal cipher suite strings.");
- }
+ jobjectArray result = makeCipherList(env, ssl_ctx);
+ SSL_CTX_free(ssl_ctx);
+ return result;
}
/**
@@ -285,8 +195,6 @@
{"nativeinit", "(Ljava/lang/String;Ljava/lang/String;[B)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_init},
{"nativesetenabledprotocols", "(J)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_setenabledprotocols},
{"nativegetsupportedciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getsupportedciphersuites},
- {"nativegetenabledciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getenabledciphersuites},
- {"nativesetenabledciphersuites", "(Ljava/lang/String;)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_setenabledciphersuites},
{"nativesetclientauth", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativesetclientauth},
{"nativefree", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativefree}
};
@@ -296,20 +204,15 @@
*/
extern "C" int register_org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl(JNIEnv* env)
{
- int ret;
- jclass clazz;
-
- clazz = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl");
-
+ jclass clazz = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl");
if (clazz == NULL) {
LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl");
return -1;
}
- ret = jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl",
+ int rc = jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl",
sMethods, NELEM(sMethods));
-
- if (ret >= 0) {
+ if (rc >= 0) {
// Note: do these after the registration of native methods, because
// there is a static method "initstatic" that's called when the
// OpenSSLServerSocketImpl class is first loaded, and that required
@@ -320,5 +223,5 @@
return -1;
}
}
- return ret;
+ return rc;
}
diff --git a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
index feae690..324dacf 100644
--- a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
+++ b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
@@ -47,20 +47,6 @@
}
/**
- * Throws java.io.IOexception with the provided message.
- */
-static void throwIOExceptionStr(JNIEnv* env, const char* message)
-{
- jclass exClass = env->FindClass("java/io/IOException");
-
- if (exClass == NULL) {
- LOGE("Unable to find class java/io/IOException");
- } else {
- env->ThrowNew(exClass, message);
- }
-}
-
-/**
* Gets the peer certificate in the chain and fills a byte array with the
* information therein.
*/
@@ -150,20 +136,15 @@
*/
static jbyteArray org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getid(JNIEnv* env, jobject object)
{
- SSL_SESSION * ssl_session;
- jbyteArray bytes;
- jbyte *tmp;
+ SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
- ssl_session = getSslSessionPointer(env, object);
-
- bytes = env->NewByteArray(ssl_session->session_id_length);
- if (bytes != NULL) {
- tmp = env->GetByteArrayElements(bytes, NULL);
- memcpy(tmp, ssl_session->session_id, ssl_session->session_id_length);
- env->ReleaseByteArrayElements(bytes, tmp, 0);
+ jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
+ if (result != NULL) {
+ jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
+ env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
}
- return bytes;
+ return result;
}
/**
diff --git a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
index 87f2af3..538b7f3 100644
--- a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
+++ b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
@@ -989,9 +989,9 @@
// 'seed == null' when no SecureRandom Object is set
// in the SSLContext.
if (seed != NULL) {
- jboolean iscopy = JNI_FALSE;
- jbyte* randseed = env->GetByteArrayElements(seed, &iscopy);
+ jbyte* randseed = env->GetByteArrayElements(seed, NULL);
RAND_seed((unsigned char*) randseed, 1024);
+ env->ReleaseByteArrayElements(seed, randseed, 0);
} else {
RAND_load_file("/dev/urandom", 1024);
}
@@ -1011,6 +1011,23 @@
*/
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
+ int mode = SSL_CTX_get_mode(ssl_ctx);
+ /*
+ * Turn on "partial write" mode. This means that SSL_write() will
+ * behave like Posix write() and possibly return after only
+ * writing a partial buffer. Note: The alternative, perhaps
+ * surprisingly, is not that SSL_write() always does full writes
+ * but that it will force you to retry write calls having
+ * preserved the full state of the original call. (This is icky
+ * and undesirable.)
+ */
+ mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
+ mode |= SSL_MODE_SMALL_BUFFERS; /* lazily allocate record buffers; usually saves
+ * 44k over the default */
+ mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH; /* enable sending of client data as soon as
+ * ClientCCS and ClientFinished are sent */
+ SSL_CTX_set_mode(ssl_ctx, mode);
+
if (privatekey != NULL) {
BIO* privatekeybio = stringToMemBuf(env, (jstring) privatekey);
EVP_PKEY* privatekeyevp =
@@ -1114,17 +1131,6 @@
fd = jniGetFDFromFileDescriptor(env, fdObject);
- /*
- * Turn on "partial write" mode. This means that SSL_write() will
- * behave like Posix write() and possibly return after only
- * writing a partial buffer. Note: The alternative, perhaps
- * surprisingly, is not that SSL_write() always does full writes
- * but that it will force you to retry write calls having
- * preserved the full state of the original call. (This is icky
- * and undesirable.)
- */
- SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
-
ssl_session = (SSL_SESSION *) session;
ret = SSL_set_fd(ssl, fd);
@@ -1404,105 +1410,82 @@
static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites(JNIEnv* env,
jobject object)
{
- SSL_CTX* ssl_ctx;
- SSL* ssl;
- jobjectArray ret;
- int i;
- const char *c;
-
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-
+ SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
if (ssl_ctx == NULL) {
return NULL;
}
-
- ssl = SSL_new(ssl_ctx);
-
- if (ssl == NULL) {
- SSL_CTX_free(ssl_ctx);
- return NULL;
- }
-
- i = 0;
- while (SSL_get_cipher_list(ssl,i) != NULL) {
- i++;
- }
-
- ret = (jobjectArray)env->NewObjectArray(i,
- env->FindClass("java/lang/String"),
- env->NewStringUTF(""));
-
- for (i=0; ; i++) {
- c=SSL_get_cipher_list(ssl,i);
- if (c == NULL) break;
-
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(c));
- }
-
- SSL_free(ssl);
+ jobjectArray result = makeCipherList(env, ssl_ctx);
SSL_CTX_free(ssl_ctx);
-
- return ret;
+ return result;
}
/**
* Loads the ciphers suites that are enabled in the OpenSSL client
* and returns them in a string array.
*/
-static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getenabledciphersuites(JNIEnv* env,
- jobject object)
+static jobjectArray OpenSSLSocketImpl_nativeGetEnabledCipherSuites(JNIEnv* env,
+ jclass, jint ssl_ctx_address)
{
- SSL_CTX* ssl_ctx;
- SSL* ssl;
- jobjectArray ret;
- int i;
- const char *c;
-
- ssl = getSslPointer(env, object, false);
- if (ssl == NULL) {
- ssl_ctx = (SSL_CTX*)env->GetIntField(object, field_ssl_ctx);
- ssl = SSL_new(ssl_ctx);
- env->SetIntField(object, field_ssl, (int)ssl);
- }
-
- i = 0;
- while (SSL_get_cipher_list(ssl,i) != NULL) {
- i++;
- }
-
- ret = (jobjectArray)env->NewObjectArray(i,
- env->FindClass("java/lang/String"),
- env->NewStringUTF(""));
-
- for (i = 0; ; i++) {
- c = SSL_get_cipher_list(ssl,i);
- if (c == NULL) break;
-
- env->SetObjectArrayElement(ret,i,env->NewStringUTF(c));
- }
-
- return ret;
+ SSL_CTX* ssl_ctx =
+ reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
+ return makeCipherList(env, ssl_ctx);
}
/**
* Sets the ciphers suites that are enabled in the OpenSSL client.
*/
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledciphersuites(JNIEnv* env, jobject object,
- jstring controlstring)
+static void OpenSSLSocketImpl_nativeSetEnabledCipherSuites(JNIEnv* env, jclass,
+ jint ssl_ctx_address, jstring controlString)
{
- SSL_CTX* ctx;
- const char *str;
- int ret;
+ SSL_CTX* ssl_ctx =
+ reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
+ setEnabledCipherSuites(env, controlString, ssl_ctx);
+}
- ctx = (SSL_CTX*)env->GetIntField(object, field_ssl_ctx);
- str = env->GetStringUTFChars(controlstring, 0);
- ret = SSL_CTX_set_cipher_list(ctx, str);
+static jobjectArray makeCipherList(JNIEnv* env, SSL* ssl) {
+ // Count the ciphers.
+ int cipherCount = 0;
+ while (SSL_get_cipher_list(ssl, cipherCount) != NULL) {
+ ++cipherCount;
+ }
- if (ret == 0) {
+ // Create a String[].
+ jclass stringClass = env->FindClass("java/lang/String");
+ if (stringClass == NULL) {
+ return NULL;
+ }
+ jobjectArray array = env->NewObjectArray(cipherCount, stringClass, NULL);
+ if (array == NULL) {
+ return NULL;
+ }
+
+ // Fill in the cipher names.
+ for (int i = 0; i < cipherCount; ++i) {
+ const char* c = SSL_get_cipher_list(ssl, i);
+ env->SetObjectArrayElement(array, i, env->NewStringUTF(c));
+ }
+ return array;
+}
+
+jobjectArray makeCipherList(JNIEnv* env, SSL_CTX* ssl_ctx) {
+ SSL* ssl = SSL_new(ssl_ctx);
+ if (ssl == NULL) {
+ return NULL;
+ }
+ jobjectArray result = makeCipherList(env, ssl);
+ SSL_free(ssl);
+ return result;
+}
+
+void setEnabledCipherSuites(JNIEnv* env, jstring controlString, SSL_CTX* ssl_ctx) {
+ const char* str = env->GetStringUTFChars(controlString, NULL);
+ int rc = SSL_CTX_set_cipher_list(ssl_ctx, str);
+ env->ReleaseStringUTFChars(controlString, str);
+ if (rc == 0) {
freeSslErrorState();
- jclass exClass = env->FindClass("java/lang/IllegalArgumentException");
- env->ThrowNew(exClass, "Illegal cipher suite strings.");
- }
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "Illegal cipher suite strings.");
+ }
}
#define SSL_AUTH_MASK 0x00007F00L
@@ -1848,8 +1831,8 @@
{"nativeaccept", "(Ljava/net/Socket;IZ)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept},
{"nativesetenabledprotocols", "(J)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledprotocols},
{"nativegetsupportedciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites},
- {"nativegetenabledciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getenabledciphersuites},
- {"nativesetenabledciphersuites", "(Ljava/lang/String;)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledciphersuites},
+ {"nativeGetEnabledCipherSuites", "(I)[Ljava/lang/String;", (void*) OpenSSLSocketImpl_nativeGetEnabledCipherSuites},
+ {"nativeSetEnabledCipherSuites", "(ILjava/lang/String;)V", (void*) OpenSSLSocketImpl_nativeSetEnabledCipherSuites},
{"nativecipherauthenticationmethod", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod},
{"nativeinterrupt", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt},
{"nativeclose", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close},
@@ -1862,63 +1845,51 @@
*/
extern "C" int register_org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl(JNIEnv* env)
{
- int ret;
- jclass clazz;
-
- clazz = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
-
+ jclass clazz = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
if (clazz == NULL) {
LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
return -1;
}
jclass socketClass = env->FindClass("java/net/Socket");
-
if (socketClass == NULL) {
LOGE("Can't find class java.net.Socket");
return -1;
}
field_mImpl = env->GetFieldID(socketClass, "impl", "Ljava/net/SocketImpl;");
-
if (field_mImpl == NULL) {
LOGE("Can't find field impl in class java.net.Socket");
return -1;
}
jclass socketImplClass = env->FindClass("java/net/SocketImpl");
-
- if(socketImplClass == NULL) {
+ if (socketImplClass == NULL) {
LOGE("Can't find class java.net.SocketImpl");
return -1;
}
field_mFD = env->GetFieldID(socketImplClass, "fd", "Ljava/io/FileDescriptor;");
-
if (field_mFD == NULL) {
LOGE("Can't find field fd in java.net.SocketImpl");
return -1;
}
jclass fdclazz = env->FindClass("java/io/FileDescriptor");
-
- if (fdclazz == NULL)
- {
+ if (fdclazz == NULL) {
LOGE("Can't find java/io/FileDescriptor");
return -1;
}
field_descriptor = env->GetFieldID(fdclazz, "descriptor", "I");
-
if (field_descriptor == NULL) {
LOGE("Can't find FileDescriptor.descriptor");
return -1;
}
- ret = jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl",
+ int rc = jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl",
sMethods, NELEM(sMethods));
-
- if (ret >= 0) {
+ if (rc >= 0) {
// Note: do these after the registration of native methods, because
// there is a static method "initstatic" that's called when the
// OpenSSLSocketImpl class is first loaded, and that required
@@ -1941,5 +1912,5 @@
return -1;
}
}
- return ret;
+ return rc;
}
diff --git a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h
index 9ed75be..e78cdd8 100644
--- a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h
+++ b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h
@@ -26,10 +26,10 @@
/**
* Structure to hold together useful JNI variables.
*/
-typedef struct {
+struct mydata_t {
JNIEnv* env;
jobject object;
-} mydata_t;
+};
/**
* Gives an array back containing all the X509 certificate's bytes.
@@ -76,9 +76,8 @@
joa = NULL;
break;
} else {
- jbyte *tmp = env->GetByteArrayElements(bytes, NULL);
- memcpy(tmp, bptr->data, bptr->length);
- env->ReleaseByteArrayElements(bytes, tmp, 0);
+ jbyte* src = reinterpret_cast<jbyte*>(bptr->data);
+ env->SetByteArrayRegion(bytes, 0, bptr->length, src);
env->SetObjectArrayElement(joa, i, bytes);
}
}
@@ -118,4 +117,7 @@
return 1;
}
+extern jobjectArray makeCipherList(JNIEnv* env, SSL_CTX* ssl);
+extern void setEnabledCipherSuites(JNIEnv* env, jstring controlString, SSL_CTX* ssl_ctx);
+
#endif
diff --git a/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java b/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
index 0e3fee3..f659919 100644
--- a/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
+++ b/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
@@ -49,6 +49,7 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import tests.util.TestEnvironment;
/**
@@ -65,6 +66,11 @@
junit.textui.TestRunner.run(SSLEngineTest.class);
}
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ TestEnvironment.reset();
+ }
+
/**
* Test for <code>SSLEngine()</code> constructor Assertion: creates
* SSLEngine object with null host and -1 port
diff --git a/x-net/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java b/x-net/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java
index 3c1fb2e..c4bae0a 100644
--- a/x-net/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java
+++ b/x-net/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java
@@ -32,6 +32,7 @@
import java.io.InputStream;
import java.net.InetAddress;
import java.security.KeyStore;
+import java.security.SecureRandom;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
@@ -585,4 +586,26 @@
.createServerSocket();
return sss;
}
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Guard against native resource leakage.",
+ method = "SSLSocket",
+ args = {}
+ )
+ public void test_creationStressTest() throws Exception {
+ KeyManager[] keyManagers = getKeyManagers();
+ // Test the default codepath, which uses /dev/urandom.
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagers, null, null);
+ for (int i = 0; i < 2048; ++i) {
+ sslContext.getServerSocketFactory().createServerSocket();
+ }
+
+ // Test the other codepath, which copies a seed from a byte[].
+ sslContext.init(keyManagers, null, new SecureRandom());
+ for (int i = 0; i < 2048; ++i) {
+ sslContext.getServerSocketFactory().createServerSocket();
+ }
+ }
}
diff --git a/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java b/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
index 46ec1d2..6eca114 100644
--- a/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
+++ b/x-net/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java
@@ -34,6 +34,7 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.security.KeyStore;
@@ -699,14 +700,15 @@
boolean notFinished = true;
SSLSession clientSession = null;
SSLContext clientSslContext = null;
+ String testData = "PING";
private String PASSWORD = "android";
String cipherSuite = (useBKS ? cipherSuiteBKS : cipherSuiteJKS);
/**
- * Implements a test SSL socket server. It wait for a connection on a given
- * port, requests client authentication (if specified), and read 256 bytes
+ * Implements a test SSL socket server. It waits for a connection on a given
+ * port, requests client authentication (if specified), and reads
* from the socket.
*/
class TestServer implements Runnable {
@@ -789,7 +791,7 @@
/**
* Implements a test SSL socket client. It open a connection to localhost on
- * a given port and writes 256 bytes to the socket.
+ * a given port and writes to the socket.
*/
class TestClient implements Runnable {
@@ -822,6 +824,9 @@
SSLSocket socket = (SSLSocket)clientSslContext.getSocketFactory().createSocket();
socket.connect(new InetSocketAddress(port));
+ OutputStream ostream = socket.getOutputStream();
+ ostream.write(testData.getBytes());
+ ostream.flush();
clientSession = socket.getSession();
while (notFinished) {
diff --git a/x-net/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java b/x-net/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java
index 5e39cb1..13a0e59 100644
--- a/x-net/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java
+++ b/x-net/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java
@@ -26,6 +26,7 @@
import java.net.*;
import java.security.KeyStore;
+import java.security.SecureRandom;
import java.lang.String;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -336,6 +337,27 @@
}
}
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Guard against native resource leakage.",
+ method = "SSLSocket",
+ args = {}
+ )
+ public void test_creationStressTest() throws Exception {
+ // Test the default codepath, which uses /dev/urandom.
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, null, null);
+ for (int i = 0; i < 2048; ++i) {
+ sslContext.getSocketFactory().createSocket();
+ }
+
+ // Test the other codepath, which copies a seed from a byte[].
+ sslContext.init(null, null, new SecureRandom());
+ for (int i = 0; i < 2048; ++i) {
+ sslContext.getSocketFactory().createSocket();
+ }
+ }
+
/**
* @throws IOException
* @tests javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener listener)
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java
index f71d289..2fd16d0 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/InnerNodeImpl.java
@@ -69,7 +69,7 @@
}
public Node getNextSibling() {
- if (parent == null || index >= parent.children.size()) {
+ if (parent == null || index + 1 >= parent.children.size()) {
return null;
}
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
index 7b786f6..7814651 100644
--- a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
@@ -252,6 +252,7 @@
public static XmlPullParserFactory newInstance (String classNames, Class context)
throws XmlPullParserException {
+ /*
if (context == null) {
//NOTE: make sure context uses the same class loader as API classes
// this is the best we can do without having access to context classloader in J2ME
@@ -259,7 +260,6 @@
context = referenceContextClass;
}
- /*
String classNamesLocation = null;
if (classNames == null || classNames.length() == 0 || "DEFAULT".equals(classNames)) {
@@ -345,5 +345,3 @@
return factory;
}
}
-
-
diff --git a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
index 40a4116..9192b1a 100644
--- a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -105,16 +105,7 @@
static jstring emptyString;
/**
- * Throws a NullPointerException.
- *
- * @param msg exception message
- */
-static void throw_NullPointerException(JNIEnv* env, const char* msg) {
- jniThrowException(env, "java/lang/NullPointerException", msg);
-}
-
-/**
- * Throw a NullPointerException.
+ * Throws OutOfMemoryError.
*/
static void throw_OutOfMemoryError(JNIEnv* env) {
jniThrowException(env, "java/lang/OutOfMemoryError", "Out of memory.");
@@ -336,15 +327,9 @@
return internString(env, parsingContext, nullTerminated);
}
-/**
- * Throw an assertion error.
- *
- * @param message to show
- */
-static void fail(JNIEnv* env, const char* message) {
- jclass clazz;
- clazz = env->FindClass("java/lang/AssertionError");
- env->ThrowNew(clazz, message);
+static void jniThrowExpatException(JNIEnv* env, XML_Error error) {
+ const char* message = XML_ErrorString(error);
+ jniThrowException(env, "org/apache/harmony/xml/ExpatException", message);
}
/**
@@ -805,18 +790,7 @@
env->CallVoidMethod(javaParser, processingInstructionMethod, javaTarget,
javaInstructionData);
- // We have to temporarily clear an exception before we can release local
- // references.
- jthrowable exception = env->ExceptionOccurred();
- if (exception != NULL) {
- env->ExceptionClear();
- }
-
env->DeleteLocalRef(javaInstructionData);
-
- if (exception != NULL) {
- env->Throw(exception);
- }
}
/**
@@ -1010,21 +984,10 @@
if (!XML_Parse(parser, (char*) characters, length, isFinal)
&& !env->ExceptionCheck()) {
- jclass clazz = env->FindClass("org/apache/harmony/xml/ExpatException");
- const char* errorMessage = XML_ErrorString(XML_GetErrorCode(parser));
- env->ThrowNew(clazz, errorMessage);
+ jniThrowExpatException(env, XML_GetErrorCode(parser));
}
- // We have to temporarily clear an exception before we can release local
- // references.
- jthrowable exception = env->ExceptionOccurred();
- if (exception) {
- env->ExceptionClear();
- env->ReleaseStringChars(xml, characters);
- env->Throw(exception);
- } else {
- env->ReleaseStringChars(xml, characters);
- }
+ env->ReleaseStringChars(xml, characters);
context->object = NULL;
context->env = NULL;
@@ -1050,21 +1013,10 @@
if (!XML_Parse(parser, ((char*) characters) + (offset << 1),
length << 1, XML_FALSE) && !env->ExceptionCheck()) {
- jclass clazz = env->FindClass("org/apache/harmony/xml/ExpatException");
- const char* errorMessage = XML_ErrorString(XML_GetErrorCode(parser));
- env->ThrowNew(clazz, errorMessage);
+ jniThrowExpatException(env, XML_GetErrorCode(parser));
}
- // We have to temporarily clear an exception before we can release local
- // references.
- jthrowable exception = env->ExceptionOccurred();
- if (exception) {
- env->ExceptionClear();
- env->ReleaseCharArrayElements(xml, characters, JNI_ABORT);
- env->Throw(exception);
- } else {
- env->ReleaseCharArrayElements(xml, characters, JNI_ABORT);
- }
+ env->ReleaseCharArrayElements(xml, characters, JNI_ABORT);
context->object = NULL;
context->env = NULL;
@@ -1090,21 +1042,10 @@
if (!XML_Parse(parser, ((char*) bytes) + offset, length, XML_FALSE)
&& !env->ExceptionCheck()) {
- jclass clazz = env->FindClass("org/apache/harmony/xml/ExpatException");
- const char* errorMessage = XML_ErrorString(XML_GetErrorCode(parser));
- env->ThrowNew(clazz, errorMessage);
+ jniThrowExpatException(env, XML_GetErrorCode(parser));
}
- // We have to temporarily clear an exception before we can release local
- // references.
- jthrowable exception = env->ExceptionOccurred();
- if (exception) {
- env->ExceptionClear();
- env->ReleaseByteArrayElements(xml, bytes, JNI_ABORT);
- env->Throw(exception);
- } else {
- env->ReleaseByteArrayElements(xml, bytes, JNI_ABORT);
- }
+ env->ReleaseByteArrayElements(xml, bytes, JNI_ABORT);
context->object = NULL;
context->env = NULL;
@@ -1308,26 +1249,21 @@
return getAttributeIndexForQName(
env, clazz, attributePointer, localName);
}
-
int localNameLength = env->GetStringUTFLength(localName);
// Create string in the same format used by Expat: "uri|localName"
+ // TODO: do we have a guarantee that uriLength and localNameLength are small?
char concatenated[uriLength + localNameLength + 2];
// Append uri.
- const char* uriBytes = env->GetStringUTFChars(uri, NULL);
- if (uriBytes == NULL) return -1;
- strcpy(concatenated, uriBytes);
- env->ReleaseStringUTFChars(uri, uriBytes);
+ env->GetStringUTFRegion(uri, 0, uriLength, concatenated);
- // Separarator.
+ // Separator.
concatenated[uriLength] = '|';
// Append local name.
- const char* localNameBytes = env->GetStringUTFChars(localName, NULL);
- if (localNameBytes == NULL) return -1;
- strcpy(concatenated + uriLength + 1, localNameBytes);
- env->ReleaseStringUTFChars(localName, localNameBytes);
+ env->GetStringUTFRegion(localName, 0, localNameLength,
+ concatenated + uriLength + 1);
return findAttributeByName(attributes, concatenated);
}
diff --git a/xml/src/test/java/org/apache/harmony/xml/AllTests.java b/xml/src/test/java/org/apache/harmony/xml/AllTests.java
new file mode 100644
index 0000000..f7fac7c
--- /dev/null
+++ b/xml/src/test/java/org/apache/harmony/xml/AllTests.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xml;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(ExpatParserTest.class);
+ return suite;
+ }
+
+}
diff --git a/xml/src/test/java/org/kxml2/io/AllTests.java b/xml/src/test/java/org/kxml2/io/AllTests.java
new file mode 100644
index 0000000..f996d25
--- /dev/null
+++ b/xml/src/test/java/org/kxml2/io/AllTests.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.kxml2.io;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+ suite.addTestSuite(KXmlSerializerTest.class);
+ return suite;
+ }
+
+}
diff --git a/xml/src/test/java/org/kxml2/io/KXmlSerializerTest.java b/xml/src/test/java/org/kxml2/io/KXmlSerializerTest.java
new file mode 100644
index 0000000..2d5ddf7
--- /dev/null
+++ b/xml/src/test/java/org/kxml2/io/KXmlSerializerTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.kxml2.io;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class KXmlSerializerTest extends TestCase {
+
+ /** the namespace */
+ final String ns = null;
+
+ public void testEmittingNullCharacterThrows() throws IOException {
+ ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ KXmlSerializer serializer = new KXmlSerializer();
+ serializer.setOutput(bytesOut, "UTF-8");
+ serializer.startDocument("UTF-8", null);
+
+ serializer.startTag(ns, "foo");
+ try {
+ serializer.text("bar\0baz");
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ serializer.startTag(ns, "bar");
+ try {
+ serializer.attribute(ns, "baz", "qu\0ux");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
index 1e1ffdd..b6c400f 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
@@ -31,6 +31,7 @@
import org.xml.sax.SAXParseException;
import tests.api.javax.xml.parsers.SAXParserFactoryTest.MyHandler;
+import tests.util.TestEnvironment;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -57,6 +58,7 @@
protected void setUp() throws Exception {
super.setUp();
+ TestEnvironment.reset();
dbf = DocumentBuilderFactory.newInstance();
cdataElements = new ArrayList<String>();
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
index 5d41356..a918ac2 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
@@ -41,6 +41,7 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import tests.util.TestEnvironment;
@TestTargetClass(SAXParserFactory.class)
public class SAXParserFactoryTest extends TestCase {
@@ -66,7 +67,9 @@
}
public void tearDown() throws Exception {
+ TestEnvironment.reset();
is1.close();
+ super.tearDown();
}
@TestTargetNew(
@@ -175,13 +178,10 @@
args = {}
)
public void test_newInstance() {
- String className = null;
try {
SAXParserFactory dtf = SAXParserFactory.newInstance();
assertNotNull("New Instance of DatatypeFactory is null", dtf);
- className = System.getProperty("javax.xml.parsers.SAXParserFactory");
-
System.setProperty("javax.xml.parsers.SAXParserFactory",
"org.apache.harmony.xml.parsers.SAXParserFactoryImpl");
@@ -205,13 +205,6 @@
}
} catch (IOException ioe) {
fail("Unexpected exception " + ioe.toString());
- } finally {
- if (className == null) {
- System.clearProperty("javax.xml.parsers.SAXParserFactory");
- } else {
- System.setProperty("javax.xml.parsers.SAXParserFactory",
- className);
- }
}
}
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java
index bc5e6a1..a1627ba 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTestSupport.java
@@ -54,7 +54,7 @@
public static final String KEY_ERROR = "error";
public static final String KEY_FATAL_ERROR = "fatalError";
public static final String KEY_WARNING = "warning";
- public static final String KEY_END_ELEMENT = "endEement";
+ public static final String KEY_END_ELEMENT = "endElement";
public static final String KEY_END_PREFIX_MAPPING = "endPrefixMapping";
public static final String KEY_IGNORABLE_WHITE_SPACE =
"ignorableWhitespace";
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java
index 27a7e78..608d52c 100644
--- a/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserAdapterTest.java
@@ -44,6 +44,7 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import tests.util.TestEnvironment;
@SuppressWarnings("deprecation")
@TestTargetClass(ParserAdapter.class)
@@ -79,11 +80,17 @@
@Override
public void setUp() {
+ TestEnvironment.reset();
adapter.setContentHandler(handler);
adapter.setDTDHandler(handler);
adapter.setErrorHandler(handler);
}
-
+
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "ParserAdapter",
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java
index dd4b1c3..113a569 100644
--- a/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/ParserFactoryTest.java
@@ -23,6 +23,7 @@
import junit.framework.TestCase;
import org.xml.sax.helpers.ParserFactory;
+import tests.util.TestEnvironment;
import java.util.Iterator;
import java.util.Properties;
@@ -32,6 +33,11 @@
@TestTargetClass(ParserFactory.class)
public class ParserFactoryTest extends TestCase {
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "makeParser",
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java
index 20488c5..0fe6f52 100644
--- a/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderAdapterTest.java
@@ -42,6 +42,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import tests.util.TestEnvironment;
@SuppressWarnings("deprecation")
@TestTargetClass(XMLReaderAdapter.class)
@@ -68,11 +69,17 @@
@Override
public void setUp() {
+ TestEnvironment.reset();
adapter.setDocumentHandler(handler);
adapter.setDTDHandler(handler);
adapter.setErrorHandler(handler);
}
-
+
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "XMLReaderAdapter",
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java
index bfb1bd1..2edb918 100644
--- a/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/XMLReaderFactoryTest.java
@@ -24,10 +24,21 @@
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLReaderFactory;
+import tests.util.TestEnvironment;
@TestTargetClass(XMLReaderFactory.class)
public class XMLReaderFactoryTest extends TestCase {
+ @Override protected void setUp() throws Exception {
+ TestEnvironment.reset();
+ super.setUp();
+ }
+
+ @Override protected void tearDown() throws Exception {
+ TestEnvironment.reset();
+ super.tearDown();
+ }
+
@TestTargetNew(
level = TestLevel.SUFFICIENT,
method = "createXMLReader",
diff --git a/xml/src/test/java/tests/xml/AllTests.java b/xml/src/test/java/tests/xml/AllTests.java
index eefae50..45ca18e 100644
--- a/xml/src/test/java/tests/xml/AllTests.java
+++ b/xml/src/test/java/tests/xml/AllTests.java
@@ -26,12 +26,17 @@
suite.addTestSuite(SimpleParserTest.class);
suite.addTestSuite(SimpleBuilderTest.class);
+ suite.addTestSuite(NodeTests.class);
//suite.addTest(tests.org.w3c.dom.AllTests.suite());
suite.addTest(tests.api.javax.xml.parsers.AllTests.suite());
suite.addTest(tests.api.org.xml.sax.AllTests.suite());
-
+ suite.addTest(tests.api.org.w3c.dom.AllTests.suite());
+ suite.addTest(tests.org.w3c.dom.AllTests.suite());
+ suite.addTest(org.apache.harmony.xml.AllTests.suite());
+ suite.addTest(org.kxml2.io.AllTests.suite());
+
return suite;
}
diff --git a/xml/src/test/java/tests/xml/NodeTests.java b/xml/src/test/java/tests/xml/NodeTests.java
new file mode 100644
index 0000000..e46e216
--- /dev/null
+++ b/xml/src/test/java/tests/xml/NodeTests.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.xml;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import java.io.ByteArrayInputStream;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+@TestTargetClass(Node.class)
+public class NodeTests extends TestCase {
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Issue #779: org.w3c.dom.Node#getNextSibling throws IndexOutOfBoundsException.",
+ method = "getNextSibling",
+ args = {}
+ )
+ public void test_getNextSibling() throws Exception {
+ // Calling getNextSibling when there is no next sibling should return null.
+ // From http://code.google.com/p/android/issues/detail?id=779.
+ ByteArrayInputStream bis = new ByteArrayInputStream("<root/>".getBytes());
+ Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bis);
+ Node root = document.getDocumentElement();
+ assertNull(root.getNextSibling());
+ }
+}