Commits

Robert Craig committed c3c416c Merge

Merge branch 'bitbucket/master' into dogfood-intent_mac

  • Participants
  • Parent commits 8b67d7c, 282761e
  • Branches intent_mac

Comments (0)

Files changed (23)

 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
-LOCAL_JNI_SHARED_LIBRARIES :=
-
-LOCAL_REQUIRED_MODULES :=
+LOCAL_STATIC_JAVA_LIBRARIES := guava
 
 include $(BUILD_PACKAGE)
-
-# Use the folloing include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))

AndroidManifest.xml

     android:versionCode="1"
     android:versionName="1.0">
 
-    <!-- SE Android Admin -->
-
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 
 # Keep all Fragments in this package, which are used by reflection.
--keep class com.android.seandroid_admin.*Fragment*
--keep class com.android.senadroid_admin.*Settings*
+-keep class com.android.seandroid_admin.*

project.properties

-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-15

res/drawable-hdpi/ic_menu_moreoverflow.png

Removed
Old image

res/drawable-hdpi/ic_menu_refresh.png

Removed
Old image

res/drawable-ldpi/ic_menu_refresh.png

Removed
Old image

res/drawable-mdpi/ic_menu_moreoverflow.png

Removed
Old image

res/drawable-mdpi/ic_menu_refresh.png

Removed
Old image

res/drawable-xhdpi/ic_menu_refresh.png

Removed
Old image

res/layout/preference_header_switch_item.xml

 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 The Android Open Source Project
+<!-- Copyright (C) 2012 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.

res/values/strings.xml

 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
 <resources>
     <string name="app_name">SEAdmin</string>
     <string name="activity_name">SEAdmin</string>

res/xml/enabled_headers.xml

 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
 <preference-headers
     xmlns:android="http://schemas.android.com/apk/res/android">
 

res/xml/mmac_fragment.xml

 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android">
 

res/xml/selinux_enforcing_fragment.xml

 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android">
 

src/com/android/seandroid_admin/MMACFragment.java

+/*
+ * Copyright (C) 2012 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.android.seandroid_admin;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.pm.SELinuxMMAC;
 import android.os.Bundle;
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import org.apache.commons.io.FileUtils;
+import com.google.common.io.Files;
 
 import java.io.File;
 import java.io.IOException;
                 public boolean onPreferenceClick(Preference preference) {
                     Log.v(TAG, "Reload of MMAC policy requested");
                     try {
-                        byte[] policy = FileUtils.readFileToByteArray(mMMACpolicyFile);
+                        byte[] policy = Files.toByteArray(mMMACpolicyFile);
                         if (!mAdmin.mDPM.setCustomPolicyFile(mAdmin.mDeviceAdmin,
                                 DevicePolicyManager.MMAC_POLICY_FILE, policy)) {
                             Toast.makeText(mActivity, "Unable to set policy", Toast.LENGTH_SHORT).show();
         
         if (mAdmin.isMMACadmin) {
             mMMACenforceCheckbox.setEnabled(true);
-            mMMACenforceCheckbox.setChecked(mAdmin.isEnforcingMMAC);
-            if (mAdmin.isEnforcingMMAC) {
+            boolean systemState = SELinuxMMAC.getEnforcingMode();
+            mMMACenforceCheckbox.setChecked(systemState);
+            if (systemState) {
                 mMMACenforceCheckbox.setSummary(mMMACenforceCheckboxSummaryChecked);
             } else {
                 mMMACenforceCheckbox.setSummary(mMMACenforceCheckboxSummaryUnchecked);

src/com/android/seandroid_admin/SEAndroidAdmin.java

+/*
+ * Copyright (C) 2012 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.android.seandroid_admin;
 
 import android.app.admin.DeviceAdminReceiver;

src/com/android/seandroid_admin/SEAndroidAdminActivity.java

+/*
+ * Copyright (C) 2012 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.android.seandroid_admin;
 

src/com/android/seandroid_admin/SEAndroidAdminFragment.java

+/*
+ * Copyright (C) 2012 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.android.seandroid_admin;
 
 import android.app.Activity;

src/com/android/seandroid_admin/SELinuxEnforcingFragment.java

+/*
+ * Copyright (C) 2012 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.android.seandroid_admin;
 
 import android.app.admin.DevicePolicyManager;
 
 import com.android.seandroid_admin.R;
 
-import org.apache.commons.io.FileUtils;
+import com.google.common.io.Files;
 
 import java.io.File;
 import java.io.IOException;
                     //XXX To do small text, will need to define own xml layout
                     CheckBoxPreference pref = new CheckBoxPreference(mActivity);
                     pref.setTitle(name);
-                    pref.setChecked(mAdmin.mDPM.getSELinuxBooleanValue(mAdmin.mDeviceAdmin, name));
+                    pref.setChecked(SELinux.getBooleanValue(name));
                     pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                         @Override
                         public boolean onPreferenceChange(Preference preference, Object newValue) {
                 public boolean onPreferenceClick(Preference preference) {
                     Log.v(TAG, "Reload of SELinux policy requested");
                     try {
-                        byte[] policy = FileUtils.readFileToByteArray(mSELinuxPolicyFile);
+                        byte[] policy = Files.toByteArray(mSELinuxPolicyFile);
                         if (!mAdmin.mDPM.setCustomPolicyFile(mAdmin.mDeviceAdmin,
                                 DevicePolicyManager.SEPOLICY_FILE_SEPOLICY, policy)) {
                             Toast.makeText(mActivity, "Unable to set policy", Toast.LENGTH_SHORT).show();
                 public boolean onPreferenceClick(Preference preference) {
                     Log.v(TAG, "Reload of Property Contexts policy requested");
                     try {
-                        byte[] policy = FileUtils.readFileToByteArray(mPropertyContextsPolicyFile);
+                        byte[] policy = Files.toByteArray(mPropertyContextsPolicyFile);
                         if (!mAdmin.mDPM.setCustomPolicyFile(mAdmin.mDeviceAdmin,
                                 DevicePolicyManager.SEPOLICY_FILE_PROPCTXS, policy)) {
                             Toast.makeText(mActivity, "Unable to set policy", Toast.LENGTH_SHORT).show();
                 public boolean onPreferenceClick(Preference preference) {
                     Log.v(TAG, "Reload of File Contexts policy requested");
                     try {
-                        byte[] policy = FileUtils.readFileToByteArray(mFileContextsPolicyFile);
+                        byte[] policy = Files.toByteArray(mFileContextsPolicyFile);
                         if (!mAdmin.mDPM.setCustomPolicyFile(mAdmin.mDeviceAdmin,
                                 DevicePolicyManager.SEPOLICY_FILE_FILECTXS, policy)) {
                             Toast.makeText(mActivity, "Unable to set policy", Toast.LENGTH_SHORT).show();
                 public boolean onPreferenceClick(Preference preference) {
                     Log.v(TAG, "Reload of SEApp Contexts policy requested");
                     try {
-                        byte[] policy = FileUtils.readFileToByteArray(mSEAppContextsPolicyFile);
+                        byte[] policy = Files.toByteArray(mSEAppContextsPolicyFile);
                         if (!mAdmin.mDPM.setCustomPolicyFile(mAdmin.mDeviceAdmin,
                                 DevicePolicyManager.SEPOLICY_FILE_SEAPPCTXS, policy)) {
                             Toast.makeText(mActivity, "Unable to set policy", Toast.LENGTH_SHORT).show();
 
         if (mAdmin.isSELinuxAdmin) {
             mSELinuxEnforceCheckbox.setEnabled(true);
-            mSELinuxEnforceCheckbox.setChecked(mAdmin.isEnforcingSELinux);
-            if (mAdmin.isEnforcingSELinux) {
+            boolean systemState = SELinux.isSELinuxEnforced();
+            mSELinuxEnforceCheckbox.setChecked(systemState);
+            if (systemState) {
                 mSELinuxEnforceCheckbox.setSummary(mSELinuxEnforceCheckboxSummaryChecked);
             } else {
                 mSELinuxEnforceCheckbox.setSummary(mSELinuxEnforceCheckboxSummaryUnchecked);

src/org/apache/commons/io/FileUtils.java

-/*
- * 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.commons.io;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * General file manipulation utilities.
- * <p>
- * Facilities are provided in the following areas:
- * <ul>
- * <li>writing to a file
- * <li>reading from a file
- * <li>make a directory including parent directories
- * <li>copying files and directories
- * <li>deleting files and directories
- * <li>converting to and from a URL
- * <li>listing files and directories by filter and extension
- * <li>comparing file content
- * <li>file last changed date
- * <li>calculating a checksum
- * </ul>
- * <p>
- * Origin of code: Excalibur, Alexandria, Commons-Utils
- *
- * @author <a href="mailto:burton@relativity.yi.org">Kevin A. Burton</A>
- * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
- * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
- * @author <a href="mailto:Christoph.Reck@dlr.de">Christoph.Reck</a>
- * @author <a href="mailto:peter@apache.org">Peter Donald</a>
- * @author <a href="mailto:jefft@apache.org">Jeff Turner</a>
- * @author Matthew Hawthorne
- * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
- * @author Stephen Colebourne
- * @author Ian Springer
- * @author Chris Eldredge
- * @author Jim Harrington
- * @author Niall Pemberton
- * @author Sandy McArthur
- * @version $Id: FileUtils.java 610810 2008-01-10 15:04:49Z niallp $
- */
-public class FileUtils {
-
-    // Only needed functions were selectively copied
-
-    /**
-     * Opens a {@link FileInputStream} for the specified file, providing better
-     * error messages than simply calling <code>new FileInputStream(file)</code>.
-     * <p>
-     * At the end of the method either the stream will be successfully opened,
-     * or an exception will have been thrown.
-     * <p>
-     * An exception is thrown if the file does not exist.
-     * An exception is thrown if the file object exists but is a directory.
-     * An exception is thrown if the file exists but cannot be read.
-     *
-     * @param file  the file to open for input, must not be <code>null</code>
-     * @return a new {@link FileInputStream} for the specified file
-     * @throws FileNotFoundException if the file does not exist
-     * @throws IOException if the file object is a directory
-     * @throws IOException if the file cannot be read
-     * @since Commons IO 1.3
-     */
-    public static FileInputStream openInputStream(File file) throws IOException {
-        if (file.exists()) {
-            if (file.isDirectory()) {
-                throw new IOException("File '" + file + "' exists but is a directory");
-            }
-            if (file.canRead() == false) {
-                throw new IOException("File '" + file + "' cannot be read");
-            }
-        } else {
-            throw new FileNotFoundException("File '" + file + "' does not exist");
-        }
-        return new FileInputStream(file);
-    }
-
-    /**
-     * Reads the contents of a file into a byte array.
-     * The file is always closed.
-     *
-     * @param file  the file to read, must not be <code>null</code>
-     * @return the file contents, never <code>null</code>
-     * @throws IOException in case of an I/O error
-     * @since Commons IO 1.1
-     */
-    public static byte[] readFileToByteArray(File file) throws IOException {
-        InputStream in = null;
-        try {
-            in = openInputStream(file);
-            return IOUtils.toByteArray(in);
-        } finally {
-            IOUtils.closeQuietly(in);
-        }
-    }
-}

src/org/apache/commons/io/IOUtils.java

-/*
- * 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.commons.io;
-
-import org.apache.commons.io.output.ByteArrayOutputStream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * General IO stream manipulation utilities.
- * <p>
- * This class provides static utility methods for input/output operations.
- * <ul>
- * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
- * <li>toXxx/read - these methods read data from a stream
- * <li>write - these methods write data to a stream
- * <li>copy - these methods copy all the data from one stream to another
- * <li>contentEquals - these methods compare the content of two streams
- * </ul>
- * <p>
- * The byte-to-char methods and char-to-byte methods involve a conversion step.
- * Two methods are provided in each case, one that uses the platform default
- * encoding and the other which allows you to specify an encoding. You are
- * encouraged to always specify an encoding because relying on the platform
- * default can lead to unexpected results, for example when moving from
- * development to production.
- * <p>
- * All the methods in this class that read a stream are buffered internally.
- * This means that there is no cause to use a <code>BufferedInputStream</code>
- * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
- * to be efficient in tests.
- * <p>
- * Wherever possible, the methods in this class do <em>not</em> flush or close
- * the stream. This is to avoid making non-portable assumptions about the
- * streams' origin and further use. Thus the caller is still responsible for
- * closing streams after use.
- * <p>
- * Origin of code: Excalibur.
- *
- * @author Peter Donald
- * @author Jeff Turner
- * @author Matthew Hawthorne
- * @author Stephen Colebourne
- * @author Gareth Davis
- * @author Ian Springer
- * @author Niall Pemberton
- * @author Sandy McArthur
- * @version $Id: IOUtils.java 481854 2006-12-03 18:30:07Z scolebourne $
- */
-public class IOUtils {
-
-    // Only needed functions were selectively copied
-
-    /**
-     * The default buffer size to use.
-     */
-    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
-
-    /**
-     * Unconditionally close an <code>InputStream</code>.
-     * <p>
-     * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
-     * This is typically used in finally blocks.
-     *
-     * @param input  the InputStream to close, may be null or already closed
-     */
-    public static void closeQuietly(InputStream input) {
-        try {
-            if (input != null) {
-                input.close();
-            }
-        } catch (IOException ioe) {
-            // ignore
-        }
-    }
-
-    /**
-     * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @return the requested byte array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     */
-    public static byte[] toByteArray(InputStream input) throws IOException {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        copy(input, output);
-        return output.toByteArray();
-    }
-    
-    /**
-     * Copy bytes from an <code>InputStream</code> to an
-     * <code>OutputStream</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     * <p>
-     * Large streams (over 2GB) will return a bytes copied value of
-     * <code>-1</code> after the copy has completed since the correct
-     * number of bytes cannot be returned as an int. For large streams
-     * use the <code>copyLarge(InputStream, OutputStream)</code> method.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @param output  the <code>OutputStream</code> to write to
-     * @return the number of bytes copied
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @throws ArithmeticException if the byte count is too large
-     * @since Commons IO 1.1
-     */
-    public static int copy(InputStream input, OutputStream output) throws IOException {
-        long count = copyLarge(input, output);
-        if (count > Integer.MAX_VALUE) {
-            return -1;
-        }
-        return (int) count;
-    }
-    
-    /**
-     * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
-     * <code>OutputStream</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @param output  the <code>OutputStream</code> to write to
-     * @return the number of bytes copied
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.3
-     */
-    public static long copyLarge(InputStream input, OutputStream output)
-            throws IOException {
-        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
-        long count = 0;
-        int n = 0;
-        while (-1 != (n = input.read(buffer))) {
-            output.write(buffer, 0, n);
-            count += n;
-        }
-        return count;
-    }
-}

src/org/apache/commons/io/output/ByteArrayOutputStream.java

-/*
- * 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.commons.io.output;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class implements an output stream in which the data is
- * written into a byte array. The buffer automatically grows as data
- * is written to it.
- * <p>
- * The data can be retrieved using <code>toByteArray()</code> and
- * <code>toString()</code>.
- * <p>
- * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
- * this class can be called after the stream has been closed without
- * generating an <tt>IOException</tt>.
- * <p>
- * This is an alternative implementation of the java.io.ByteArrayOutputStream
- * class. The original implementation only allocates 32 bytes at the beginning.
- * As this class is designed for heavy duty it starts at 1024 bytes. In contrast
- * to the original it doesn't reallocate the whole memory block but allocates
- * additional buffers. This way no buffers need to be garbage collected and
- * the contents don't have to be copied to the new buffer. This class is
- * designed to behave exactly like the original. The only exception is the
- * deprecated toString(int) method that has been ignored.
- *
- * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
- * @author Holger Hoffstatte
- * @version $Id: ByteArrayOutputStream.java 610010 2008-01-08 14:50:59Z niallp $
- */
-public class ByteArrayOutputStream extends OutputStream {
-
-    /** A singleton empty byte array. */
-    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
-    /** The list of buffers, which grows and never reduces. */
-    private List<byte[]> buffers = new ArrayList<byte[]>();
-    /** The index of the current buffer. */
-    private int currentBufferIndex;
-    /** The total count of bytes in all the filled buffers. */
-    private int filledBufferSum;
-    /** The current buffer. */
-    private byte[] currentBuffer;
-    /** The total count of bytes written. */
-    private int count;
-
-    /**
-     * Creates a new byte array output stream. The buffer capacity is
-     * initially 1024 bytes, though its size increases if necessary.
-     */
-    public ByteArrayOutputStream() {
-        this(1024);
-    }
-
-    /**
-     * Creates a new byte array output stream, with a buffer capacity of
-     * the specified size, in bytes.
-     *
-     * @param size  the initial size
-     * @throws IllegalArgumentException if size is negative
-     */
-    public ByteArrayOutputStream(int size) {
-        if (size < 0) {
-            throw new IllegalArgumentException(
-                "Negative initial size: " + size);
-        }
-        needNewBuffer(size);
-    }
-
-    /**
-     * Return the appropriate <code>byte[]</code> buffer
-     * specified by index.
-     *
-     * @param index  the index of the buffer required
-     * @return the buffer
-     */
-    private byte[] getBuffer(int index) {
-        return buffers.get(index);
-    }
-
-    /**
-     * Makes a new buffer available either by allocating
-     * a new one or re-cycling an existing one.
-     *
-     * @param newcount  the size of the buffer if one is created
-     */
-    private void needNewBuffer(int newcount) {
-        if (currentBufferIndex < buffers.size() - 1) {
-            //Recycling old buffer
-            filledBufferSum += currentBuffer.length;
-
-            currentBufferIndex++;
-            currentBuffer = getBuffer(currentBufferIndex);
-        } else {
-            //Creating new buffer
-            int newBufferSize;
-            if (currentBuffer == null) {
-                newBufferSize = newcount;
-                filledBufferSum = 0;
-            } else {
-                newBufferSize = Math.max(
-                    currentBuffer.length << 1,
-                    newcount - filledBufferSum);
-                filledBufferSum += currentBuffer.length;
-            }
-
-            currentBufferIndex++;
-            currentBuffer = new byte[newBufferSize];
-            buffers.add(currentBuffer);
-        }
-    }
-
-    /**
-     * Write the bytes to byte array.
-     * @param b the bytes to write
-     * @param off The start offset
-     * @param len The number of bytes to write
-     */
-    @Override
-    public void write(byte[] b, int off, int len) {
-        if ((off < 0)
-                || (off > b.length)
-                || (len < 0)
-                || ((off + len) > b.length)
-                || ((off + len) < 0)) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
-            return;
-        }
-        synchronized (this) {
-            int newcount = count + len;
-            int remaining = len;
-            int inBufferPos = count - filledBufferSum;
-            while (remaining > 0) {
-                int part = Math.min(remaining, currentBuffer.length - inBufferPos);
-                System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part);
-                remaining -= part;
-                if (remaining > 0) {
-                    needNewBuffer(newcount);
-                    inBufferPos = 0;
-                }
-            }
-            count = newcount;
-        }
-    }
-
-    /**
-     * Write a byte to byte array.
-     * @param b the byte to write
-     */
-    @Override
-    public synchronized void write(int b) {
-        int inBufferPos = count - filledBufferSum;
-        if (inBufferPos == currentBuffer.length) {
-            needNewBuffer(count + 1);
-            inBufferPos = 0;
-        }
-        currentBuffer[inBufferPos] = (byte) b;
-        count++;
-    }
-
-    /**
-     * Writes the entire contents of the specified input stream to this
-     * byte stream. Bytes from the input stream are read directly into the
-     * internal buffers of this streams.
-     *
-     * @param in the input stream to read from
-     * @return total number of bytes read from the input stream
-     *         (and written to this stream)
-     * @throws IOException if an I/O error occurs while reading the input stream
-     * @since Commons IO 1.4
-     */
-    public synchronized int write(InputStream in) throws IOException {
-        int readCount = 0;
-        int inBufferPos = count - filledBufferSum;
-        int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
-        while (n != -1) {
-            readCount += n;
-            inBufferPos += n;
-            count += n;
-            if (inBufferPos == currentBuffer.length) {
-                needNewBuffer(currentBuffer.length);
-                inBufferPos = 0;
-            }
-            n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
-        }
-        return readCount;
-    }
-
-    /**
-     * Return the current size of the byte array.
-     * @return the current size of the byte array
-     */
-    public synchronized int size() {
-        return count;
-    }
-
-    /**
-     * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
-     * this class can be called after the stream has been closed without
-     * generating an <tt>IOException</tt>.
-     *
-     * @throws IOException never (this method should not declare this exception
-     * but it has to now due to backwards compatability)
-     */
-    @Override
-    public void close() throws IOException {
-        //nop
-    }
-
-    /**
-     * @see java.io.ByteArrayOutputStream#reset()
-     */
-    public synchronized void reset() {
-        count = 0;
-        filledBufferSum = 0;
-        currentBufferIndex = 0;
-        currentBuffer = getBuffer(currentBufferIndex);
-    }
-
-    /**
-     * Writes the entire contents of this byte stream to the
-     * specified output stream.
-     *
-     * @param out  the output stream to write to
-     * @throws IOException if an I/O error occurs, such as if the stream is closed
-     * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
-     */
-    public synchronized void writeTo(OutputStream out) throws IOException {
-        int remaining = count;
-        for (int i = 0; i < buffers.size(); i++) {
-            byte[] buf = getBuffer(i);
-            int c = Math.min(buf.length, remaining);
-            out.write(buf, 0, c);
-            remaining -= c;
-            if (remaining == 0) {
-                break;
-            }
-        }
-    }
-
-    /**
-     * Gets the curent contents of this byte stream as a byte array.
-     * The result is independent of this stream.
-     *
-     * @return the current contents of this output stream, as a byte array
-     * @see java.io.ByteArrayOutputStream#toByteArray()
-     */
-    public synchronized byte[] toByteArray() {
-        int remaining = count;
-        if (remaining == 0) {
-            return EMPTY_BYTE_ARRAY;
-        }
-        byte newbuf[] = new byte[remaining];
-        int pos = 0;
-        for (int i = 0; i < buffers.size(); i++) {
-            byte[] buf = getBuffer(i);
-            int c = Math.min(buf.length, remaining);
-            System.arraycopy(buf, 0, newbuf, pos, c);
-            pos += c;
-            remaining -= c;
-            if (remaining == 0) {
-                break;
-            }
-        }
-        return newbuf;
-    }
-
-    /**
-     * Gets the curent contents of this byte stream as a string.
-     * @return the contents of the byte array as a String
-     * @see java.io.ByteArrayOutputStream#toString()
-     */
-    @Override
-    public String toString() {
-        return new String(toByteArray());
-    }
-
-    /**
-     * Gets the curent contents of this byte stream as a string
-     * using the specified encoding.
-     *
-     * @param enc  the name of the character encoding
-     * @return the string converted from the byte array
-     * @throws UnsupportedEncodingException if the encoding is not supported
-     * @see java.io.ByteArrayOutputStream#toString(String)
-     */
-    public String toString(String enc) throws UnsupportedEncodingException {
-        return new String(toByteArray(), enc);
-    }
-
-}