Consider using {@link #asByteBuffer()}, which is a safer method to avoid an additional array copy because it does not + * provide a way to modify the underlying buffer. As the method name implies, this is unsafe. If you're not sure, don't use + * this. The only guarantees given to the user of this method is that the SDK itself won't modify the underlying byte + * array.
+ * + * @see #asByteBuffer() to prevent creating an additional array copy safely. + */ + public final byte[] asByteArrayUnsafe() { + return bytes; + } + /** * Retrieve the output as a string. * diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/ResponseBytes.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/ResponseBytes.java index 61da73085c1b..2b3ed0523cca 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/ResponseBytes.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/ResponseBytes.java @@ -15,10 +15,15 @@ package software.amazon.awssdk.core; +import static software.amazon.awssdk.utils.FunctionalUtils.invokeSafely; + +import java.io.InputStream; +import java.io.UncheckedIOException; import java.util.Arrays; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.core.sync.ResponseTransformer; +import software.amazon.awssdk.utils.IoUtils; import software.amazon.awssdk.utils.ToString; import software.amazon.awssdk.utils.Validate; @@ -31,15 +36,38 @@ public final class ResponseBytesAs the method name implies, this is unsafe. Use {@link #fromByteArray(Object, byte[])} unless you're sure you know the
+ * risks.
+ */
+ public static As the method name implies, this is unsafe. Use {@link #fromByteArray(byte[])} unless you're sure you know the risks.
+ */
+ public static SdkBytes fromByteArrayUnsafe(byte[] bytes) {
+ Validate.paramNotNull(bytes, "bytes");
+ return new SdkBytes(bytes);
+ }
+
/**
* Create {@link SdkBytes} from a string, using the provided charset.
*/
@@ -100,7 +112,7 @@ public static SdkBytes fromInputStream(InputStream inputStream) {
@Override
public String toString() {
return ToString.builder("SdkBytes")
- .add("bytes", wrappedBytes())
+ .add("bytes", asByteArrayUnsafe())
.build();
}
}
diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/ResponseBytesTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/ResponseBytesTest.java
new file mode 100644
index 000000000000..f41a0179b6ad
--- /dev/null
+++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/ResponseBytesTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.core;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class ResponseBytesTest {
+ private static final Object OBJECT = new Object();
+ @Test
+ public void fromByteArrayCreatesCopy() {
+ byte[] input = new byte[] { 'a' };
+ byte[] output = ResponseBytes.fromByteArray(OBJECT, input).asByteArrayUnsafe();
+
+ input[0] = 'b';
+ assertThat(output).isNotEqualTo(input);
+ }
+
+ @Test
+ public void asByteArrayCreatesCopy() {
+ byte[] input = new byte[] { 'a' };
+ byte[] output = ResponseBytes.fromByteArrayUnsafe(OBJECT, input).asByteArray();
+
+ input[0] = 'b';
+ assertThat(output).isNotEqualTo(input);
+ }
+
+ @Test
+ public void fromByteArrayUnsafeAndAsByteArrayUnsafeDoNotCopy() {
+ byte[] input = new byte[] { 'a' };
+ byte[] output = ResponseBytes.fromByteArrayUnsafe(OBJECT, input).asByteArrayUnsafe();
+
+ assertThat(output).isSameAs(input);
+ }
+}
diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/SdkBytesTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/SdkBytesTest.java
new file mode 100644
index 000000000000..1503f08ae54b
--- /dev/null
+++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/SdkBytesTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.core;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class SdkBytesTest {
+ @Test
+ public void fromByteArrayCreatesCopy() {
+ byte[] input = new byte[] { 'a' };
+ byte[] output = SdkBytes.fromByteArray(input).asByteArrayUnsafe();
+
+ input[0] = 'b';
+ assertThat(output).isNotEqualTo(input);
+ }
+
+ @Test
+ public void asByteArrayCreatesCopy() {
+ byte[] input = new byte[] { 'a' };
+ byte[] output = SdkBytes.fromByteArrayUnsafe(input).asByteArray();
+
+ input[0] = 'b';
+ assertThat(output).isNotEqualTo(input);
+ }
+
+ @Test
+ public void fromByteArrayUnsafeAndAsByteArrayUnsafeDoNotCopy() {
+ byte[] input = new byte[] { 'a' };
+ byte[] output = SdkBytes.fromByteArrayUnsafe(input).asByteArrayUnsafe();
+
+ assertThat(output).isSameAs(input);
+ }
+}