module hunt.http.codec.websocket.model.extension.compress.ByteAccumulator; import hunt.http.Exceptions; import hunt.io.BufferUtils; import hunt.io.ByteBuffer; import hunt.collection; import hunt.Exceptions; import std.format; class ByteAccumulator { private List!(byte[]) chunks; private int maxSize; private int length = 0; this(int maxOverallBufferSize) { this.maxSize = maxOverallBufferSize; chunks = new ArrayList!(byte[])(); } void copyChunk(byte[] buf, int offset, int length) { if (this.length + length > maxSize) { throw new MessageTooLargeException("Frame is too large"); } byte[] copy = new byte[length - offset]; // System.arraycopy(buf, offset, copy, 0, length); copy[0..length] = buf[offset .. offset+length]; chunks.add(copy); this.length += length; } int getLength() { return length; } void transferTo(ByteBuffer buffer) { if (buffer.remaining() < length) { string msg = format("Not enough space in ByteBuffer remaining [%d] " ~ "for accumulated buffers length [%d]", buffer.remaining(), length); throw new IllegalArgumentException(msg); } int position = buffer.position(); foreach (byte[] chunk ; chunks) { buffer.put(chunk, 0, cast(int)chunk.length); } BufferUtils.flipToFlush(buffer, position); } }