4242import org .eclipse .jetty .io .internal .ContentCopier ;
4343import org .eclipse .jetty .io .internal .ContentSourceByteBuffer ;
4444import org .eclipse .jetty .io .internal .ContentSourceConsumer ;
45+ import org .eclipse .jetty .io .internal .ContentSourceRange ;
4546import org .eclipse .jetty .io .internal .ContentSourceRetainableByteBuffer ;
4647import org .eclipse .jetty .io .internal .ContentSourceString ;
4748import org .eclipse .jetty .util .Blocker ;
@@ -169,9 +170,13 @@ interface Factory
169170 * Creates a new {@link Content.Source}.
170171 *
171172 * @param bufferPool the {@link ByteBufferPool.Sized} to get buffers from. {@code null} means allocate new buffers as needed.
172- * @param offset the offset byte of the resource to start from.
173+ * @param offset the offset byte of the content to start from.
174+ * Must be greater than or equal to 0 and less than the content length (if known).
173175 * @param length the length of the content to make available, -1 for the full length.
176+ * If the size of the content is known, the length may be truncated to the content size minus the offset.
174177 * @return a {@link Content.Source}.
178+ * @throws IndexOutOfBoundsException if the offset or length are out of range.
179+ * @see TypeUtil#checkOffsetLengthSize(long, long, long)
175180 */
176181 Content .Source newContentSource (ByteBufferPool .Sized bufferPool , long offset , long length );
177182 }
@@ -198,16 +203,42 @@ static Content.Source from(Path path)
198203
199204 /**
200205 * Create a {@code Content.Source} from a {@link Path}.
206+ *
201207 * @param path The {@link Path}s to use as the source.
202- * @param offset The offset in bytes from which to start the source
203- * @param length The length in bytes of the source.
204- * @return A {@code Content.Source}
208+ * @param offset the offset byte of the content to start from.
209+ * Must be greater than or equal to 0 and less than the content length (if known).
210+ * @param length the length of the content to make available, -1 for the full length.
211+ * If the size of the content is known, the length may be truncated to the content size minus the offset.
212+ * @return a {@link Content.Source}.
213+ * @throws IndexOutOfBoundsException if the offset or length are out of range.
214+ * @see TypeUtil#checkOffsetLengthSize(long, long, long)
205215 */
206216 static Content .Source from (Path path , long offset , long length )
207217 {
208218 return from (null , path , offset , length );
209219 }
210220
221+ /**
222+ * Wrap a {@link Content.Source} to make it appear as a sub-range of the original.
223+ *
224+ * @param source The {@link Content.Source} to wrap.
225+ * @param offset the offset byte of the content to start from.
226+ * Must be greater than or equal to 0 and less than the content length (if known).
227+ * @param length the length of the content to make available, -1 for the full length.
228+ * If the size of the content is known, the length may be truncated to the content size minus the offset.
229+ * @return a {@link Content.Source}.
230+ * @throws IndexOutOfBoundsException if the offset or length are out of range.
231+ * @see TypeUtil#checkOffsetLengthSize(long, long, long)
232+ */
233+ static Content .Source from (Content .Source source , long offset , long length )
234+ {
235+ // If the offset and length include the full content, then do not wrap.
236+ if (offset == 0 && (length == -1 || length == source .getLength ()))
237+ return source ;
238+
239+ return new ContentSourceRange (source , offset , length );
240+ }
241+
211242 /**
212243 * Create a {@code Content.Source} from a {@link Path}.
213244 * @param byteBufferPool The {@link org.eclipse.jetty.io.ByteBufferPool.Sized} to use for any internal buffers.
@@ -223,9 +254,13 @@ static Content.Source from(ByteBufferPool.Sized byteBufferPool, Path path)
223254 * Create a {@code Content.Source} from a {@link Path}.
224255 * @param byteBufferPool The {@link org.eclipse.jetty.io.ByteBufferPool.Sized} to use for any internal buffers.
225256 * @param path The {@link Path}s to use as the source.
226- * @param offset The offset in bytes from which to start the source
227- * @param length The length in bytes of the source, -1 for the full length.
228- * @return A {@code Content.Source}
257+ * @param offset the offset byte of the content to start from.
258+ * Must be greater than or equal to 0 and less than the content length (if known).
259+ * @param length the length of the content to make available, -1 for the full length.
260+ * If the size of the content is known, the length may be truncated to the content size minus the offset.
261+ * @return a {@link Content.Source}.
262+ * @throws IndexOutOfBoundsException if the offset or length are out of range.
263+ * @see TypeUtil#checkOffsetLengthSize(long, long, long)
229264 */
230265 static Content .Source from (ByteBufferPool .Sized byteBufferPool , Path path , long offset , long length )
231266 {
@@ -247,9 +282,13 @@ static Content.Source from(ByteBufferPool.Sized byteBufferPool, ByteChannel byte
247282 * Create a {@code Content.Source} from a {@link ByteChannel}.
248283 * @param byteBufferPool The {@link org.eclipse.jetty.io.ByteBufferPool.Sized} to use for any internal buffers.
249284 * @param seekableByteChannel The {@link ByteChannel}s to use as the source.
250- * @param offset The offset in bytes from which to start the source
251- * @param length The length in bytes of the source.
252- * @return A {@code Content.Source}
285+ * @param offset the offset byte of the content to start from.
286+ * Must be greater than or equal to 0 and less than the content length (if known).
287+ * @param length the length of the content to make available, -1 for the full length.
288+ * If the size of the content is known, the length may be truncated to the content size minus the offset.
289+ * @return a {@link Content.Source}.
290+ * @throws IndexOutOfBoundsException if the offset or length are out of range.
291+ * @see TypeUtil#checkOffsetLengthSize(long, long, long)
253292 */
254293 static Content .Source from (ByteBufferPool .Sized byteBufferPool , SeekableByteChannel seekableByteChannel , long offset , long length )
255294 {
@@ -276,9 +315,13 @@ static Content.Source from(ByteBufferPool.Sized byteBufferPool, InputStream inpu
276315 * Create a {@code Content.Source} from an {@link InputStream}.
277316 * @param byteBufferPool The {@link org.eclipse.jetty.io.ByteBufferPool.Sized} to use for any internal buffers.
278317 * @param inputStream The {@link InputStream}s to use as the source.
279- * @param offset The offset in bytes from which to start the source
280- * @param length The number of bytes to read from the source, or -1 to read to the end of the stream
281- * @return A {@code Content.Source}
318+ * @param offset the offset byte of the resource to start from.
319+ * Must be greater than or equal to 0 and less than the resource size (if known).
320+ * @param length the length of the content to make available, or -1 for the full length available.
321+ * The length may be truncated if the stream ends sooner.
322+ * @return a {@link Content.Source}.
323+ * @throws IndexOutOfBoundsException if the offset or length are out of range.
324+ * @see TypeUtil#checkOffsetLengthSize(long, long, long)
282325 */
283326 static Content .Source from (ByteBufferPool .Sized byteBufferPool , InputStream inputStream , long offset , long length )
284327 {
@@ -961,6 +1004,19 @@ static Chunk from(ByteBuffer byteBuffer, boolean last)
9611004 return last ? EOF : EMPTY ;
9621005 }
9631006
1007+ /**
1008+ * <p>Creates a Chunk with the given RetainableByteBuffer</p>
1009+ * <p>The returned Chunk is not {@link #retain() retained} and {@link #release() releasing it
1010+ * will release the passed buffer}.</p>
1011+ * @param buffer the RetainableByteBuffer to use to back the returned Chunk
1012+ * @param last whether the Chunk is the last one
1013+ * @return a buffer as a Chunk
1014+ */
1015+ static Chunk from (RetainableByteBuffer buffer , boolean last )
1016+ {
1017+ return new ByteBufferChunk .WithRetainableByteBuffer (buffer , last );
1018+ }
1019+
9641020 /**
9651021 * <p>Creates a Chunk with the given ByteBuffer.</p>
9661022 * <p>The returned Chunk must be {@link #release() released}.</p>
0 commit comments