diff --git a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java index 6993ff5beb..b9f68869e3 100644 --- a/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java +++ b/buffer/src/main/java/io/netty/buffer/ByteBufUtil.java @@ -58,7 +58,7 @@ public final class ByteBufUtil { private static final int MAX_CHAR_BUFFER_SIZE; private static final int THREAD_LOCAL_BUFFER_SIZE; private static final int MAX_BYTES_PER_CHAR_UTF8 = - (int) CharsetUtil.getEncoder(CharsetUtil.UTF_8).maxBytesPerChar(); + (int) CharsetUtil.encoder(CharsetUtil.UTF_8).maxBytesPerChar(); static final ByteBufAllocator DEFAULT_ALLOCATOR; @@ -488,7 +488,7 @@ public final class ByteBufUtil { } static ByteBuf encodeString0(ByteBufAllocator alloc, boolean enforceHeap, CharBuffer src, Charset charset) { - final CharsetEncoder encoder = CharsetUtil.getEncoder(charset); + final CharsetEncoder encoder = CharsetUtil.encoder(charset); int length = (int) ((double) src.remaining() * encoder.maxBytesPerChar()); boolean release = true; final ByteBuf dst; @@ -524,7 +524,7 @@ public final class ByteBufUtil { if (len == 0) { return StringUtil.EMPTY_STRING; } - final CharsetDecoder decoder = CharsetUtil.getDecoder(charset); + final CharsetDecoder decoder = CharsetUtil.decoder(charset); final int maxLength = (int) ((double) len * decoder.maxCharsPerByte()); CharBuffer dst = CHAR_BUFFERS.get(); if (dst.length() < maxLength) { diff --git a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequest.java b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequest.java index 5b6d56f0b3..83196a0eaf 100644 --- a/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequest.java +++ b/codec-socks/src/main/java/io/netty/handler/codec/socks/SocksAuthRequest.java @@ -27,7 +27,7 @@ import java.nio.charset.CharsetEncoder; * @see SocksAuthRequestDecoder */ public final class SocksAuthRequest extends SocksRequest { - private static final CharsetEncoder asciiEncoder = CharsetUtil.getEncoder(CharsetUtil.US_ASCII); + private static final CharsetEncoder asciiEncoder = CharsetUtil.encoder(CharsetUtil.US_ASCII); private static final SocksSubnegotiationVersion SUBNEGOTIATION_VERSION = SocksSubnegotiationVersion.AUTH_PASSWORD; private final String username; private final String password; diff --git a/common/src/main/java/io/netty/util/CharsetUtil.java b/common/src/main/java/io/netty/util/CharsetUtil.java index 74c0a3dc91..8b094e9bb3 100644 --- a/common/src/main/java/io/netty/util/CharsetUtil.java +++ b/common/src/main/java/io/netty/util/CharsetUtil.java @@ -16,6 +16,7 @@ package io.netty.util; import io.netty.util.internal.InternalThreadLocalMap; +import static io.netty.util.internal.ObjectUtil.checkNotNull; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; @@ -62,51 +63,113 @@ public final class CharsetUtil { public static final Charset US_ASCII = Charset.forName("US-ASCII"); /** - * Returns a cached thread-local {@link CharsetEncoder} for the specified - * charset. + * @deprecated Use {@link #encoder(Charset)}. */ + @Deprecated public static CharsetEncoder getEncoder(Charset charset) { - if (charset == null) { - throw new NullPointerException("charset"); - } + return encoder(charset); + } + + /** + * Returns a new {@link CharsetEncoder} for the {@link Charset} with specified error actions. + * + * @param charset The specified charset + * @param malformedInputAction The encoder's action for malformed-input errors + * @param unmappableCharacterAction The encoder's action for unmappable-character errors + * @return The encoder for the specified charset + */ + public static CharsetEncoder encoder(Charset charset, CodingErrorAction malformedInputAction, + CodingErrorAction unmappableCharacterAction) { + checkNotNull(charset, "charset"); + CharsetEncoder e = charset.newEncoder(); + e.onMalformedInput(malformedInputAction).onUnmappableCharacter(unmappableCharacterAction); + return e; + } + + /** + * Returns a new {@link CharsetEncoder} for the {@link Charset} with the specified error action. + * + * @param charset The specified charset + * @param codingErrorAction The encoder's action for malformed-input and unmappable-character errors + * @return The encoder for the specified charset + */ + public static CharsetEncoder encoder(Charset charset, CodingErrorAction codingErrorAction) { + return encoder(charset, codingErrorAction, codingErrorAction); + } + + /** + * Returns a cached thread-local {@link CharsetEncoder} for the specified {@link Charset}. + * + * @param charset The specified charset + * @return The encoder for the specified charset + */ + public static CharsetEncoder encoder(Charset charset) { + checkNotNull(charset, "charset"); Map map = InternalThreadLocalMap.get().charsetEncoderCache(); CharsetEncoder e = map.get(charset); if (e != null) { - e.reset(); - e.onMalformedInput(CodingErrorAction.REPLACE); - e.onUnmappableCharacter(CodingErrorAction.REPLACE); + e.reset().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE); return e; } - e = charset.newEncoder(); - e.onMalformedInput(CodingErrorAction.REPLACE); - e.onUnmappableCharacter(CodingErrorAction.REPLACE); + e = encoder(charset, CodingErrorAction.REPLACE, CodingErrorAction.REPLACE); map.put(charset, e); return e; } /** - * Returns a cached thread-local {@link CharsetDecoder} for the specified - * charset. + * @deprecated Use {@link #decoder(Charset)}. */ + @Deprecated public static CharsetDecoder getDecoder(Charset charset) { - if (charset == null) { - throw new NullPointerException("charset"); - } + return decoder(charset); + } + + /** + * Returns a new {@link CharsetDecoder} for the {@link Charset} with specified error actions. + * + * @param charset The specified charset + * @param malformedInputAction The decoder's action for malformed-input errors + * @param unmappableCharacterAction The decoder's action for unmappable-character errors + * @return The decoder for the specified charset + */ + public static CharsetDecoder decoder(Charset charset, CodingErrorAction malformedInputAction, + CodingErrorAction unmappableCharacterAction) { + checkNotNull(charset, "charset"); + CharsetDecoder d = charset.newDecoder(); + d.onMalformedInput(malformedInputAction).onUnmappableCharacter(unmappableCharacterAction); + return d; + } + + /** + * Returns a new {@link CharsetDecoder} for the {@link Charset} with the specified error action. + * + * @param charset The specified charset + * @param codingErrorAction The decoder's action for malformed-input and unmappable-character errors + * @return The decoder for the specified charset + */ + public static CharsetDecoder decoder(Charset charset, CodingErrorAction codingErrorAction) { + return decoder(charset, codingErrorAction, codingErrorAction); + } + + /** + * Returns a cached thread-local {@link CharsetDecoder} for the specified {@link Charset}. + * + * @param charset The specified charset + * @return The decoder for the specified charset + */ + public static CharsetDecoder decoder(Charset charset) { + checkNotNull(charset, "charset"); Map map = InternalThreadLocalMap.get().charsetDecoderCache(); CharsetDecoder d = map.get(charset); if (d != null) { - d.reset(); - d.onMalformedInput(CodingErrorAction.REPLACE); - d.onUnmappableCharacter(CodingErrorAction.REPLACE); + d.reset().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE); return d; } - d = charset.newDecoder(); - d.onMalformedInput(CodingErrorAction.REPLACE); - d.onUnmappableCharacter(CodingErrorAction.REPLACE); + d = decoder(charset, CodingErrorAction.REPLACE, CodingErrorAction.REPLACE); map.put(charset, d); return d; }