2222import java .nio .charset .Charset ;
2323import java .nio .charset .StandardCharsets ;
2424import java .nio .file .Path ;
25+ import java .util .Arrays ;
2526import java .util .Optional ;
2627import java .util .concurrent .ExecutorService ;
2728import org .reactivestreams .Publisher ;
2829import org .reactivestreams .Subscriber ;
2930import software .amazon .awssdk .annotations .SdkPublicApi ;
30- import software .amazon .awssdk .core .internal .async .ByteArrayAsyncRequestBody ;
31+ import software .amazon .awssdk .core .internal .async .ByteBuffersAsyncRequestBody ;
3132import software .amazon .awssdk .core .internal .async .FileAsyncRequestBody ;
3233import software .amazon .awssdk .core .internal .async .InputStreamWithExecutorAsyncRequestBody ;
3334import software .amazon .awssdk .core .internal .util .Mimetype ;
5253 * </p>
5354 *
5455 * @see FileAsyncRequestBody
55- * @see ByteArrayAsyncRequestBody
56+ * @see ByteBuffersAsyncRequestBody
5657 */
5758@ SdkPublicApi
5859public interface AsyncRequestBody extends SdkPublisher <ByteBuffer > {
@@ -124,11 +125,11 @@ static AsyncRequestBody fromFile(File file) {
124125 * @param string The string to provide.
125126 * @param cs The {@link Charset} to use.
126127 * @return Implementation of {@link AsyncRequestBody} that uses the specified string.
127- * @see ByteArrayAsyncRequestBody
128+ * @see ByteBuffersAsyncRequestBody
128129 */
129130 static AsyncRequestBody fromString (String string , Charset cs ) {
130- return new ByteArrayAsyncRequestBody ( string . getBytes ( cs ),
131- Mimetype . MIMETYPE_TEXT_PLAIN + "; charset=" + cs . name ( ));
131+ return ByteBuffersAsyncRequestBody . from ( Mimetype . MIMETYPE_TEXT_PLAIN + "; charset=" + cs . name ( ),
132+ string . getBytes ( cs ));
132133 }
133134
134135 /**
@@ -150,18 +151,69 @@ static AsyncRequestBody fromString(String string) {
150151 * @return AsyncRequestBody instance.
151152 */
152153 static AsyncRequestBody fromBytes (byte [] bytes ) {
153- return new ByteArrayAsyncRequestBody (bytes , Mimetype .MIMETYPE_OCTET_STREAM );
154+ byte [] clonedBytes = bytes .clone ();
155+ return ByteBuffersAsyncRequestBody .from (clonedBytes );
154156 }
155157
156158 /**
157- * Creates a {@link AsyncRequestBody} from a {@link ByteBuffer}. Buffer contents are copied so any modifications
158- * made to the original {@link ByteBuffer} are not reflected in the {@link AsyncRequestBody}.
159+ * Creates a {@link AsyncRequestBody} from a byte array. The contents of the byte array are copied so modifications to the
160+ * original byte array are not reflected in the {@link AsyncRequestBody}.
161+ *
162+ * @param bytes The bytes to send to the service.
163+ * @return AsyncRequestBody instance.
164+ */
165+ static AsyncRequestBody fromBytesUnsafe (byte [] bytes ) {
166+ return ByteBuffersAsyncRequestBody .from (bytes );
167+ }
168+
169+ /**
170+ * Creates a {@link AsyncRequestBody} from a {@link ByteBuffer}. Buffer contents are copied with the position set to zero, the
171+ * mark if defined is discarded, this is to ensure modifications made to the original {@link ByteBuffer} are not reflected in
172+ * the {@link AsyncRequestBody}.
159173 *
160174 * @param byteBuffer ByteBuffer to send to the service.
161175 * @return AsyncRequestBody instance.
162176 */
163177 static AsyncRequestBody fromByteBuffer (ByteBuffer byteBuffer ) {
164- return fromBytes (BinaryUtils .copyAllBytesFrom (byteBuffer ));
178+ ByteBuffer immutableCopy = BinaryUtils .immutableCopyOf (byteBuffer );
179+ immutableCopy .rewind ();
180+ return ByteBuffersAsyncRequestBody .of (null , immutableCopy );
181+ }
182+
183+ /**
184+ * Creates a {@link AsyncRequestBody} from a {@link ByteBuffer}.
185+ *
186+ * @param byteBuffer ByteBuffer to send to the service.
187+ * @return AsyncRequestBody instance.
188+ */
189+ static AsyncRequestBody fromByteBufferUnsafe (ByteBuffer byteBuffer ) {
190+ return ByteBuffersAsyncRequestBody .of (null , byteBuffer );
191+ }
192+
193+ /**
194+ * Creates a {@link AsyncRequestBody} from an array of {@link ByteBuffer}. Each Buffers contents are copied with their
195+ * positions set to zero and marks if defined are discarded, this is to ensure modifications made to the original array of
196+ * {@link ByteBuffer} are not reflected in the {@link AsyncRequestBody}.
197+ *
198+ * @param byteBuffers ByteBuffer[] to send to the service.
199+ * @return AsyncRequestBody instance.
200+ */
201+ static AsyncRequestBody fromByteBuffers (ByteBuffer ... byteBuffers ) {
202+ ByteBuffer [] immutableCopy = Arrays .stream (byteBuffers )
203+ .map (BinaryUtils ::immutableCopyOf )
204+ .peek (ByteBuffer ::rewind )
205+ .toArray (ByteBuffer []::new );
206+ return ByteBuffersAsyncRequestBody .of (null , immutableCopy );
207+ }
208+
209+ /**
210+ * Creates a {@link AsyncRequestBody} from an array of {@link ByteBuffer}.
211+ *
212+ * @param byteBuffers ByteBuffer[] to send to the service.
213+ * @return AsyncRequestBody instance.
214+ */
215+ static AsyncRequestBody fromByteBuffersUnsafe (ByteBuffer ... byteBuffers ) {
216+ return ByteBuffersAsyncRequestBody .of (null , byteBuffers );
165217 }
166218
167219 /**
0 commit comments