From 0144ba6369b90a3ad830101a9496f1d4471c07d0 Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 13 Dec 2024 17:14:57 +0500 Subject: [PATCH] minor improvements --- .../java/org/takes/rq/ChunkedInputStream.java | 148 ++++++++++++------ 1 file changed, 102 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/takes/rq/ChunkedInputStream.java b/src/main/java/org/takes/rq/ChunkedInputStream.java index 0dee6bcbf..11c1af2e6 100644 --- a/src/main/java/org/takes/rq/ChunkedInputStream.java +++ b/src/main/java/org/takes/rq/ChunkedInputStream.java @@ -42,6 +42,70 @@ */ final class ChunkedInputStream extends InputStream { + /** + * Empty value for checking the result. + */ + private static final int EMPTY_VALUE = -1; + + /** + * Default radix value. + */ + private static final int DEFAULT_RADIX = 16; + + /** + * Double slash value. + */ + private static final int DOUBLE_SLASH = '\\'; + + /** + * Quoted string value. + */ + private static final int QUOTED_VALUE = '\"'; + + /** + * Next line value. + */ + private static final int NEXT_LINE = '\n'; + + /** + * R value. + */ + private static final int R_VALUE = '\r'; + + /** + * Semicolon value. + */ + private static final int SEMICOLON = ';'; + + /** + * Exception for bad state. + */ + private static final String BAD_STATE = "Bad state"; + + /** + * Exception for bad chunk. + */ + private static final String BAD_CHUNK_SIZE = "Bad chunk size: %s"; + + /** + * Exception for chunk stream end. + */ + private static final String END_OF_STREAM = "chunked stream ended unexpectedly"; + + /** + * Exception for crlf expectation state. + */ + private static final String CRLF_EXPECTED = "CRLF expected at end of chunk: "; + + /** + * Exception for protocol violation. + */ + private static final String BAD_PROTOCOL = String.format( + "%s%s", + "Protocol violation: Unexpected", + " single newline character in chunk size" + ); + /** * The inputstream that we're wrapping. */ @@ -85,7 +149,7 @@ public int read() throws IOException { } final int result; if (this.eof) { - result = -1; + result = ChunkedInputStream.EMPTY_VALUE; } else { ++this.pos; result = this.origin.read(); @@ -101,7 +165,7 @@ public int read(final byte[] buf, final int off, final int len) } final int result; if (this.eof) { - result = -1; + result = ChunkedInputStream.EMPTY_VALUE; } else { final int shift = Math.min(len, this.size - this.pos); final int count = this.origin.read(buf, off, shift); @@ -137,7 +201,7 @@ private void readCrlf() throws IOException { throw new IOException( String.format( "%s %d%s%d", - "CRLF expected at end of chunk: ", + ChunkedInputStream.CRLF_EXPECTED, crsymbol, "/", lfsymbol @@ -174,7 +238,7 @@ private static int chunkSize(final InputStream stream) throws IOException { final ByteArrayOutputStream baos = ChunkedInputStream.sizeLine(stream); final String data = baos.toString(Charset.defaultCharset().name()); - final int separator = data.indexOf(';'); + final int separator = data.indexOf(ChunkedInputStream.SEMICOLON); final Text number = new Trimmed( new Unchecked<>( new Ternary<>( @@ -186,15 +250,13 @@ private static int chunkSize(final InputStream stream) ); try { return Integer.parseInt( - new UncheckedText( - number - ).asString(), - 16 + new UncheckedText(number).asString(), + ChunkedInputStream.DEFAULT_RADIX ); } catch (final NumberFormatException ex) { throw new IOException( String.format( - "Bad chunk size: %s", + ChunkedInputStream.BAD_CHUNK_SIZE, baos.toString(Charset.defaultCharset().name()) ), ex @@ -202,28 +264,6 @@ private static int chunkSize(final InputStream stream) } } - /** - * Possible states of FSM that used to find chunk size. - */ - private enum State { - /** - * Normal. - */ - NORMAL, - /** - * If \r was scanned. - */ - R, - /** - * Inside quoted string. - */ - QUOTED_STRING, - /** - * End. - */ - END; - } - /** * Extract line with chunk size from stream. * @param stream Input stream. @@ -251,8 +291,8 @@ private static ByteArrayOutputStream sizeLine(final InputStream stream) private static State next(final InputStream stream, final State state, final ByteArrayOutputStream line) throws IOException { final int next = stream.read(); - if (next == -1) { - throw new IOException("chunked stream ended unexpectedly"); + if (next == ChunkedInputStream.EMPTY_VALUE) { + throw new IOException(ChunkedInputStream.END_OF_STREAM); } final State result; switch (state) { @@ -260,23 +300,17 @@ private static State next(final InputStream stream, final State state, result = nextNormal(state, line, next); break; case R: - if (next == '\n') { + if (next == ChunkedInputStream.NEXT_LINE) { result = State.END; } else { - throw new IOException( - String.format( - "%s%s", - "Protocol violation: Unexpected", - " single newline character in chunk size" - ) - ); + throw new IOException(ChunkedInputStream.BAD_PROTOCOL); } break; case QUOTED_STRING: result = nextQuoted(stream, state, line, next); break; default: - throw new IllegalStateException("Bad state"); + throw new IllegalStateException(ChunkedInputStream.BAD_STATE); } return result; } @@ -292,10 +326,10 @@ private static State nextNormal(final State state, final ByteArrayOutputStream line, final int next) { final State result; switch (next) { - case '\r': + case ChunkedInputStream.R_VALUE: result = State.R; break; - case '\"': + case ChunkedInputStream.QUOTED_VALUE: result = State.QUOTED_STRING; break; default: @@ -321,11 +355,11 @@ private static State nextQuoted(final InputStream stream, final State state, throws IOException { final State result; switch (next) { - case '\\': + case ChunkedInputStream.DOUBLE_SLASH: result = state; line.write(stream.read()); break; - case '\"': + case ChunkedInputStream.QUOTED_VALUE: result = State.NORMAL; break; default: @@ -335,4 +369,26 @@ private static State nextQuoted(final InputStream stream, final State state, } return result; } + + /** + * Possible states of FSM that used to find chunk size. + */ + private enum State { + /** + * Normal. + */ + NORMAL, + /** + * If \r was scanned. + */ + R, + /** + * Inside quoted string. + */ + QUOTED_STRING, + /** + * End. + */ + END; + } }