chibenwa commented on code in PR #2145:
URL: https://github.com/apache/james-project/pull/2145#discussion_r1535378432
##
server/protocols/protocols-imap4/src/main/java/org/apache/james/imapserver/netty/ChunkedStreamWithSize.java:
##
@@ -0,0 +1,150 @@
+/
+ * 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.james.imapserver.netty;
+
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.stream.ChunkedInput;
+import io.netty.util.internal.ObjectUtil;
+
+/**
+ * A clone of io.netty.handler.stream.ChunkedStream class, with getChunkSize
method added
+ */
+public class ChunkedStreamWithSize implements ChunkedInput {
+
+static final int DEFAULT_CHUNK_SIZE = 8192;
+
+private final PushbackInputStream in;
+private final int chunkSize;
+private long offset;
+private boolean closed;
+
+/**
+ * Creates a new instance that fetches data from the specified stream.
+ */
+public ChunkedStreamWithSize(InputStream in) {
+this(in, DEFAULT_CHUNK_SIZE);
+}
+
+/**
+ * Creates a new instance that fetches data from the specified stream.
+ *
+ * @param chunkSize the number of bytes to fetch on each
+ * {@link #readChunk(ChannelHandlerContext)} call
+ */
+public ChunkedStreamWithSize(InputStream in, int chunkSize) {
+ObjectUtil.checkNotNull(in, "in");
+ObjectUtil.checkPositive(chunkSize, "chunkSize");
+
+if (in instanceof PushbackInputStream) {
+this.in = (PushbackInputStream) in;
+} else {
+this.in = new PushbackInputStream(in);
+}
+this.chunkSize = chunkSize;
+}
+
+/**
+ * Returns the number of transferred bytes.
+ */
+public long transferredBytes() {
+return offset;
+}
+
+@Override
+public boolean isEndOfInput() throws Exception {
+if (closed) {
+return true;
+}
+if (in.available() > 0) {
+return false;
+}
+
+int b = in.read();
+if (b < 0) {
+return true;
+} else {
+in.unread(b);
+return false;
+}
+}
+
+@Override
+public void close() throws Exception {
+closed = true;
+in.close();
+}
+
+@Deprecated
+@Override
+public ByteBuf readChunk(ChannelHandlerContext ctx) throws Exception {
+return readChunk(ctx.alloc());
+}
+
+@Override
+public ByteBuf readChunk(ByteBufAllocator allocator) throws Exception {
+if (isEndOfInput()) {
+return null;
+}
+
+final int availableBytes = in.available();
+final int chunkSize;
+if (availableBytes <= 0) {
+chunkSize = this.chunkSize;
+} else {
+chunkSize = Math.min(this.chunkSize, in.available());
+}
+
+boolean release = true;
+ByteBuf buffer = allocator.buffer(chunkSize);
+try {
+// transfer to buffer
+int written = buffer.writeBytes(in, chunkSize);
+if (written < 0) {
+return null;
+}
+offset += written;
+release = false;
+return buffer;
+} finally {
+if (release) {
+buffer.release();
+}
+}
+}
+
+@Override
+public long length() {
+return -1;
+}
+
+@Override
+public long progress() {
+return offset;
+}
+
+public int getChunkSize() {
+return chunkSize;
+}
Review Comment:
Well James do actually chucks some kinda transformations of
"ByteArrayInputStream".