Skip to content

Commit

Permalink
buffer: Add write(CharBuffer)
Browse files Browse the repository at this point in the history
  • Loading branch information
jknack committed May 26, 2024
1 parent a2f52c3 commit f95df82
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 40 deletions.
67 changes: 40 additions & 27 deletions jooby/src/main/java/io/jooby/buffer/DataBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -241,35 +241,48 @@ default DataBuffer write(CharSequence charSequence, Charset charset) {
Assert.notNull(charSequence, "CharSequence must not be null");
Assert.notNull(charset, "Charset must not be null");
if (!charSequence.isEmpty()) {
CharsetEncoder encoder =
charset
.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
CharBuffer src = CharBuffer.wrap(charSequence);
int averageSize = (int) Math.ceil(src.remaining() * encoder.averageBytesPerChar());
ensureWritable(averageSize);
while (true) {
CoderResult cr;
if (src.hasRemaining()) {
try (ByteBufferIterator iterator = writableByteBuffers()) {
Assert.state(iterator.hasNext(), "No ByteBuffer available");
ByteBuffer dest = iterator.next();
cr = encoder.encode(src, dest, true);
if (cr.isUnderflow()) {
cr = encoder.flush(dest);
}
writePosition(writePosition() + dest.position());
write(CharBuffer.wrap(charSequence), charset);
}
return this;
}

/**
* Write the given {@code CharBuffer} using the given {@code Charset}, starting at the current
* writing position.
*
* @param src the char sequence to write into this buffer
* @param charset the charset to encode the char sequence with
* @return this buffer
* @since 5.1.4
*/
default DataBuffer write(CharBuffer src, Charset charset) {
CharsetEncoder encoder =
charset
.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
int averageSize = (int) Math.ceil(src.remaining() * encoder.averageBytesPerChar());
ensureWritable(averageSize);
while (true) {
CoderResult cr;
if (src.hasRemaining()) {
try (ByteBufferIterator iterator = writableByteBuffers()) {
Assert.state(iterator.hasNext(), "No ByteBuffer available");
ByteBuffer dest = iterator.next();
cr = encoder.encode(src, dest, true);
if (cr.isUnderflow()) {
cr = encoder.flush(dest);
}
} else {
cr = CoderResult.UNDERFLOW;
}
if (cr.isUnderflow()) {
break;
} else if (cr.isOverflow()) {
int maxSize = (int) Math.ceil(src.remaining() * encoder.maxBytesPerChar());
ensureWritable(maxSize);
writePosition(writePosition() + dest.position());
}
} else {
cr = CoderResult.UNDERFLOW;
}
if (cr.isUnderflow()) {
break;
} else if (cr.isOverflow()) {
int maxSize = (int) Math.ceil(src.remaining() * encoder.maxBytesPerChar());
ensureWritable(maxSize);
}
}
return this;
Expand Down
26 changes: 13 additions & 13 deletions jooby/src/main/java/io/jooby/buffer/DataBufferWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
import java.nio.CharBuffer;
import java.nio.charset.Charset;

import edu.umd.cs.findbugs.annotations.NonNull;

class DataBufferWriter extends Writer {
private final DataBuffer dataBuffer;
private final Charset charset;

private boolean closed;

public DataBufferWriter(DataBuffer dataBuffer, Charset charset) {
Expand All @@ -22,33 +23,32 @@ public DataBufferWriter(DataBuffer dataBuffer, Charset charset) {
}

@Override
public void write(char[] buffer, int off, int len) throws IOException {
public void write(int c) throws IOException {
checkClosed();
dataBuffer.write(CharBuffer.wrap(buffer, off, len), charset);
super.write(c);
}

@Override
public void write(int c) throws IOException {
checkClosed();
super.write(c);
public void write(@NonNull char[] source) throws IOException {
write(source, 0, source.length);
}

@Override
public void write(String str) throws IOException {
public void write(@NonNull char[] source, int off, int len) throws IOException {
checkClosed();
dataBuffer.write(str, charset);
dataBuffer.write(CharBuffer.wrap(source, off, len), charset);
}

@Override
public void write(char[] cbuf) throws IOException {
public void write(@NonNull String source) throws IOException {
checkClosed();
dataBuffer.write(CharBuffer.wrap(cbuf), charset);
dataBuffer.write(CharBuffer.wrap(source), charset);
}

@Override
public void write(String str, int off, int len) throws IOException {
public void write(@NonNull String source, int off, int len) throws IOException {
checkClosed();
dataBuffer.write(CharBuffer.wrap(str, off, off + len), charset);
dataBuffer.write(CharBuffer.wrap(source, off, off + len), charset);
}

@Override
Expand All @@ -64,7 +64,7 @@ public void close() {

private void checkClosed() throws IOException {
if (this.closed) {
throw new IOException("DataBufferOutputStream is closed");
throw new IOException("DataBufferWriter is closed");
}
}
}

0 comments on commit f95df82

Please sign in to comment.