Resolved issue: NETTY-268 (Use Charset instead of String to represent a character set.)

* Replaced String charsetName with Charset
* Added o.j.n.util.CharsetUtil
This commit is contained in:
Trustin Lee 2009-12-29 05:52:00 +00:00
parent 55078d87bd
commit 24b59bbfa9
32 changed files with 419 additions and 110 deletions

View File

@ -21,6 +21,7 @@ import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.util.NoSuchElementException;
@ -530,27 +531,45 @@ public abstract class AbstractChannelBuffer implements ChannelBuffer {
return new ByteBuffer[] { toByteBuffer(index, length) };
}
public String toString(String charsetName) {
return toString(readerIndex, readableBytes(), charsetName);
public String toString(Charset charset) {
return toString(readerIndex, readableBytes(), charset);
}
public String toString(String charsetName, ChannelBufferIndexFinder terminatorFinder) {
return toString(readerIndex, readableBytes(), charsetName, terminatorFinder);
public String toString(Charset charset, ChannelBufferIndexFinder terminatorFinder) {
return toString(readerIndex, readableBytes(), charset, terminatorFinder);
}
public String toString(
int index, int length, String charsetName,
int index, int length, Charset charset,
ChannelBufferIndexFinder terminatorFinder) {
if (terminatorFinder == null) {
return toString(index, length, charsetName);
return toString(index, length, charset);
}
int terminatorIndex = indexOf(index, index + length, terminatorFinder);
if (terminatorIndex < 0) {
return toString(index, length, charsetName);
return toString(index, length, charset);
}
return toString(index, terminatorIndex - index, charsetName);
return toString(index, terminatorIndex - index, charset);
}
public String toString(int index, int length, String charsetName,
ChannelBufferIndexFinder terminatorFinder) {
return toString(index, length, Charset.forName(charsetName), terminatorFinder);
}
public String toString(int index, int length, String charsetName) {
return toString(index, length, Charset.forName(charsetName));
}
public String toString(String charsetName,
ChannelBufferIndexFinder terminatorFinder) {
return toString(Charset.forName(charsetName), terminatorFinder);
}
public String toString(String charsetName) {
return toString(Charset.forName(charsetName));
}
public int indexOf(int fromIndex, int toIndex, byte value) {

View File

@ -24,6 +24,7 @@ import java.nio.ByteOrder;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
/**
@ -300,22 +301,22 @@ public class ByteBufferBackedChannelBuffer extends AbstractChannelBuffer {
}
}
public String toString(int index, int length, String charsetName) {
public String toString(int index, int length, Charset charset) {
if (!buffer.isReadOnly() && buffer.hasArray()) {
try {
return new String(
buffer.array(), index + buffer.arrayOffset(), length,
charsetName);
charset.name());
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException(charsetName);
throw new UnsupportedCharsetException(charset.name());
}
} else {
byte[] tmp = new byte[length];
((ByteBuffer) buffer.duplicate().position(index)).get(tmp);
try {
return new String(tmp, charsetName);
return new String(tmp, charset.name());
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException(charsetName);
throw new UnsupportedCharsetException(charset.name());
}
}
}

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.NoSuchElementException;
@ -1619,6 +1620,12 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
* if the specified character set name is not supported by the
* current VM
*/
String toString(Charset charset);
/**
* @deprecated Use {@link #toString(Charset)} instead.
*/
@Deprecated
String toString(String charsetName);
/**
@ -1633,6 +1640,13 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
* if the specified character set name is not supported by the
* current VM
*/
String toString(
Charset charset, ChannelBufferIndexFinder terminatorFinder);
/**
* @deprecated Use {@link #toString(Charset, ChannelBufferIndexFinder)} instead.
*/
@Deprecated
String toString(
String charsetName, ChannelBufferIndexFinder terminatorFinder);
@ -1646,6 +1660,12 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
* if the specified character set name is not supported by the
* current VM
*/
String toString(int index, int length, Charset charset);
/**
* @deprecated Use {@link #toString(int, int, Charset)} instead.
*/
@Deprecated
String toString(int index, int length, String charsetName);
/**
@ -1659,6 +1679,14 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
* if the specified character set name is not supported by the
* current VM
*/
String toString(
int index, int length, Charset charset,
ChannelBufferIndexFinder terminatorFinder);
/**
* @deprecated Use {@link #toString(int, int, Charset, ChannelBufferIndexFinder)} instead.
*/
@Deprecated
String toString(
int index, int length, String charsetName,
ChannelBufferIndexFinder terminatorFinder);

View File

@ -18,6 +18,7 @@ package org.jboss.netty.buffer;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.List;
@ -663,8 +664,16 @@ public class ChannelBuffers {
* The new buffer's {@code readerIndex} and {@code writerIndex} are
* {@code 0} and the length of the encoded string respectively.
*/
public static ChannelBuffer copiedBuffer(String string, Charset charset) {
return copiedBuffer(BIG_ENDIAN, string, charset);
}
/**
* @deprecated Use {@link #copiedBuffer(String, Charset)} instead.
*/
@Deprecated
public static ChannelBuffer copiedBuffer(String string, String charsetName) {
return copiedBuffer(BIG_ENDIAN, string, charsetName);
return copiedBuffer(string, Charset.forName(charsetName));
}
/**
@ -674,14 +683,22 @@ public class ChannelBuffers {
* {@code writerIndex} are {@code 0} and the length of the encoded string
* respectively.
*/
public static ChannelBuffer copiedBuffer(ByteOrder endianness, String string, String charsetName) {
public static ChannelBuffer copiedBuffer(ByteOrder endianness, String string, Charset charset) {
try {
return wrappedBuffer(endianness, string.getBytes(charsetName));
return wrappedBuffer(endianness, string.getBytes(charset.name()));
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException(charsetName);
throw new UnsupportedCharsetException(charset.name());
}
}
/**
* @deprecated Use {@link #copiedBuffer(ByteOrder, String, Charset)} instead.
*/
@Deprecated
public static ChannelBuffer copiedBuffer(ByteOrder endianness, String string, String charsetName) {
return copiedBuffer(endianness, string, Charset.forName(charsetName));
}
/**
* Creates a read-only buffer which disallows any modification operations
* on the specified {@code buffer}. The new buffer has the same

View File

@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Collections;
@ -587,11 +588,11 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
return buffers.toArray(new ByteBuffer[buffers.size()]);
}
public String toString(int index, int length, String charsetName) {
public String toString(int index, int length, Charset charset) {
int componentId = componentId(index);
if (index + length <= indices[componentId + 1]) {
return components[componentId].toString(
index - indices[componentId], length, charsetName);
index - indices[componentId], length, charset);
}
byte[] data = new byte[length];
@ -610,9 +611,9 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
}
try {
return new String(data, charsetName);
return new String(data, charset.name());
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException(charsetName);
throw new UnsupportedCharsetException(charset.name());
}
}

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
/**
@ -180,7 +181,7 @@ public class DuplicatedChannelBuffer extends AbstractChannelBuffer implements Wr
return buffer.toByteBuffer(index, length);
}
public String toString(int index, int length, String charsetName) {
return buffer.toString(index, length, charsetName);
public String toString(int index, int length, Charset charset) {
return buffer.toString(index, length, charset);
}
}

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
/**
@ -290,7 +291,7 @@ public class DynamicChannelBuffer extends AbstractChannelBuffer {
return buffer.toByteBuffer(index, length);
}
public String toString(int index, int length, String charsetName) {
return buffer.toString(index, length, charsetName);
public String toString(int index, int length, Charset charset) {
return buffer.toString(index, length, charset);
}
}

View File

@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
/**
@ -206,11 +207,11 @@ public abstract class HeapChannelBuffer extends AbstractChannelBuffer {
return ByteBuffer.wrap(array, index, length).order(order());
}
public String toString(int index, int length, String charsetName) {
public String toString(int index, int length, Charset charset) {
try {
return new String(array, index, length, charsetName);
return new String(array, index, length, charset.name());
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException(charsetName);
throw new UnsupportedCharsetException(charset.name());
}
}
}

View File

@ -23,6 +23,7 @@ import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
/**
* A derived buffer which forbids any write requests to its parent. It is
@ -190,8 +191,8 @@ public class ReadOnlyChannelBuffer extends AbstractChannelBuffer implements Wrap
return bufs;
}
public String toString(int index, int length, String charsetName) {
return buffer.toString(index, length, charsetName);
public String toString(int index, int length, Charset charset) {
return buffer.toString(index, length, charset);
}
public int capacity() {

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
/**
@ -213,9 +214,9 @@ public class SlicedChannelBuffer extends AbstractChannelBuffer implements Wrappe
return buffer.toByteBuffer(index + adjustment, length);
}
public String toString(int index, int length, String charsetName) {
public String toString(int index, int length, Charset charset) {
checkIndex(index, length);
return buffer.toString(index + adjustment, length, charsetName);
return buffer.toString(index + adjustment, length, charset);
}
private void checkIndex(int index) {

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
/**
@ -207,9 +208,9 @@ public class TruncatedChannelBuffer extends AbstractChannelBuffer implements Wra
return buffer.toByteBuffer(index, length);
}
public String toString(int index, int length, String charsetName) {
public String toString(int index, int length, Charset charset) {
checkIndex(index, length);
return buffer.toString(index, length, charsetName);
return buffer.toString(index, length, charset);
}
private void checkIndex(int index) {

View File

@ -41,7 +41,8 @@ import org.jboss.netty.channel.ServerChannel;
* recipients.add(channelB);
* ..
* <strong>recipients.write(ChannelBuffers.copiedBuffer(
* "Service will shut down for maintenance in 5 minutes.", "UTF-8"));</strong>
* "Service will shut down for maintenance in 5 minutes.",
* CharsetUtil.UTF_8));</strong>
* </pre>
*
* <h3>Simplify shutdown process with {@link ChannelGroup}</h3>

View File

@ -39,6 +39,7 @@ import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.handler.stream.ChunkedFile;
import org.jboss.netty.util.CharsetUtil;
/**
* @author The Netty Project (netty-dev@lists.jboss.org)
@ -159,7 +160,8 @@ public class HttpStaticFileServerHandler extends SimpleChannelUpstreamHandler {
response.setHeader(
HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8");
response.setContent(ChannelBuffers.copiedBuffer(
"Failure: " + status.toString() + "\r\n", "UTF-8"));
"Failure: " + status.toString() + "\r\n",
CharsetUtil.UTF_8));
// Close the connection as soon as the error message is sent.
ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);

View File

@ -41,6 +41,7 @@ import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.jboss.netty.util.CharsetUtil;
/**
* @author The Netty Project (netty-dev@lists.jboss.org)
@ -98,7 +99,7 @@ public class HttpRequestHandler extends SimpleChannelUpstreamHandler {
} else {
ChannelBuffer content = request.getContent();
if (content.readable()) {
responseContent.append("CONTENT: " + content.toString("UTF-8") + "\r\n");
responseContent.append("CONTENT: " + content.toString(CharsetUtil.UTF_8) + "\r\n");
}
writeResponse(e);
}
@ -121,14 +122,14 @@ public class HttpRequestHandler extends SimpleChannelUpstreamHandler {
writeResponse(e);
} else {
responseContent.append("CHUNK: " + chunk.getContent().toString("UTF-8") + "\r\n");
responseContent.append("CHUNK: " + chunk.getContent().toString(CharsetUtil.UTF_8) + "\r\n");
}
}
}
private void writeResponse(MessageEvent e) {
// Convert the response content to a ChannelBuffer.
ChannelBuffer buf = ChannelBuffers.copiedBuffer(responseContent.toString(), "UTF-8");
ChannelBuffer buf = ChannelBuffers.copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
responseContent.setLength(0);
// Decide whether to close the connection or not.

View File

@ -22,6 +22,7 @@ import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.HttpChunk;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.util.CharsetUtil;
/**
* @author The Netty Project (netty-dev@lists.jboss.org)
@ -60,7 +61,7 @@ public class HttpResponseHandler extends SimpleChannelUpstreamHandler {
ChannelBuffer content = response.getContent();
if (content.readable()) {
System.out.println("CONTENT {");
System.out.println(content.toString("UTF-8"));
System.out.println(content.toString(CharsetUtil.UTF_8));
System.out.println("} END OF CONTENT");
}
}
@ -70,7 +71,7 @@ public class HttpResponseHandler extends SimpleChannelUpstreamHandler {
readingChunks = false;
System.out.println("} END OF CHUNKED CONTENT");
} else {
System.out.print(chunk.getContent().toString("UTF-8"));
System.out.print(chunk.getContent().toString(CharsetUtil.UTF_8));
System.out.flush();
}
}

View File

@ -26,6 +26,7 @@ import org.jboss.netty.channel.socket.DatagramChannelFactory;
import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import org.jboss.netty.util.CharsetUtil;
/**
* A UDP broadcast client that asks for a quote of the moment (QOTM) to
@ -47,8 +48,8 @@ public class QuoteOfTheMomentClient {
// Configure the pipeline.
ChannelPipeline p = b.getPipeline();
p.addLast("encoder", new StringEncoder("UTF-8"));
p.addLast("decoder", new StringDecoder("UTF-8"));
p.addLast("encoder", new StringEncoder(CharsetUtil.ISO_8859_1));
p.addLast("decoder", new StringDecoder(CharsetUtil.ISO_8859_1));
p.addLast("handler", new QuoteOfTheMomentClientHandler());
// Enable broadcast

View File

@ -25,6 +25,7 @@ import org.jboss.netty.channel.socket.DatagramChannelFactory;
import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import org.jboss.netty.util.CharsetUtil;
/**
* A UDP server that responds to the QOTM (quote of the moment) request to a
@ -46,8 +47,8 @@ public class QuoteOfTheMomentServer {
// Configure the pipeline.
ChannelPipeline p = b.getPipeline();
p.addLast("encoder", new StringEncoder("UTF-8"));
p.addLast("decoder", new StringDecoder("UTF-8"));
p.addLast("encoder", new StringEncoder(CharsetUtil.ISO_8859_1));
p.addLast("decoder", new StringDecoder(CharsetUtil.ISO_8859_1));
p.addLast("handler", new QuoteOfTheMomentServerHandler());
// Enable broadcast

View File

@ -25,6 +25,7 @@ import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
import org.jboss.netty.util.CharsetUtil;
/**
* Decodes a Base64-encoded {@link ChannelBuffer} or US-ASCII {@link String}
@ -69,8 +70,7 @@ public class Base64Decoder extends OneToOneDecoder {
protected Object decode(ChannelHandlerContext ctx, Channel channel, Object msg)
throws Exception {
if (msg instanceof String) {
msg = ChannelBuffers.wrappedBuffer(
((String) msg).getBytes("ASCII"));
msg = ChannelBuffers.copiedBuffer((String) msg, CharsetUtil.US_ASCII);
} else if (!(msg instanceof ChannelBuffer)) {
return msg;
}

View File

@ -31,7 +31,7 @@ import org.jboss.netty.handler.codec.string.StringDecoder;
* {@link StringDecoder} without setting up the {@link ChannelPipeline} and
* other mock objects by yourself:
* <pre>
* ChannelBuffer base64Data = ChannelBuffer.copiedBuffer("Zm9vYmFy", "ASCII");
* ChannelBuffer base64Data = ChannelBuffer.copiedBuffer("Zm9vYmFy", CharsetUtil.US_ASCII);
*
* DecoderEmbedder&lt;String&gt; embedder = new DecoderEmbedder&lt;String&gt;(
* new Base64Decoder(), new StringDecoder());

View File

@ -39,7 +39,7 @@ import org.jboss.netty.handler.codec.string.StringEncoder;
* embedded.offer(data);
*
* ChannelBuffer encoded = embedded.poll();
* assert encoded.toString("ASCII").equals("Zm9vYmFy");
* assert encoded.toString(CharsetUtil.US_ASCII).equals("Zm9vYmFy");
* </pre>
*
* @author The Netty Project (netty-dev@lists.jboss.org)

View File

@ -15,6 +15,10 @@
*/
package org.jboss.netty.handler.codec.http;
import java.nio.charset.Charset;
import org.jboss.netty.util.CharsetUtil;
/**
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Andy Taylor (andy.taylor@jboss.org)
@ -64,7 +68,7 @@ class HttpCodecUtil {
static final byte DOUBLE_QUOTE = '"';
static final String DEFAULT_CHARSET = "UTF-8";
static final Charset DEFAULT_CHARSET = CharsetUtil.UTF_8;
private HttpCodecUtil() {
super();
@ -80,7 +84,7 @@ class HttpCodecUtil {
throw new IllegalArgumentException(
"name contains non-ascii character: " + name);
}
// Check prohibited characters.
switch (c) {
case '=': case ',': case ';': case ' ': case ':':
@ -97,15 +101,15 @@ class HttpCodecUtil {
if (value == null) {
throw new NullPointerException("value");
}
// 0 - the previous character was neither CR nor LF
// 1 - the previous character was CR
// 2 - the previous character was LF
int state = 0;
for (int i = 0; i < value.length(); i ++) {
char c = value.charAt(i);
// Check the absolutely prohibited characters.
switch (c) {
case '\f':
@ -115,7 +119,7 @@ class HttpCodecUtil {
throw new IllegalArgumentException(
"value contains a prohibited character '\\v': " + value);
}
// Check the CRLF (HT | SP) pattern
switch (state) {
case 0:
@ -149,7 +153,7 @@ class HttpCodecUtil {
}
}
}
if (state != 0) {
throw new IllegalArgumentException(
"value must not end with '\\r' or '\\n':" + value);

View File

@ -28,6 +28,7 @@ import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
import org.jboss.netty.util.CharsetUtil;
/**
* Encodes an {@link HttpMessage} or an {@link HttpChunk} into
@ -52,7 +53,8 @@ import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
@ChannelPipelineCoverage("all")
public abstract class HttpMessageEncoder extends OneToOneEncoder {
private static final ChannelBuffer LAST_CHUNK = copiedBuffer("0\r\n\r\n", "ASCII");
private static final ChannelBuffer LAST_CHUNK =
copiedBuffer("0\r\n\r\n", CharsetUtil.US_ASCII);
/**
* Creates a new instance.
@ -96,7 +98,9 @@ public abstract class HttpMessageEncoder extends OneToOneEncoder {
int contentLength = content.readableBytes();
return wrappedBuffer(
copiedBuffer(Integer.toHexString(contentLength), "ASCII"),
copiedBuffer(
Integer.toHexString(contentLength),
CharsetUtil.US_ASCII),
wrappedBuffer(CRLF),
content.slice(content.readerIndex(), contentLength),
wrappedBuffer(CRLF));

View File

@ -18,6 +18,7 @@ package org.jboss.netty.handler.codec.http;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.HashMap;
@ -49,7 +50,7 @@ public class QueryStringDecoder {
private static final Pattern PARAM_PATTERN = Pattern.compile("([^=]*)=([^&]*)&*");
private final String charset;
private final Charset charset;
private final String uri;
private String path;
private final Map<String, List<String>> params = new HashMap<String, List<String>>();
@ -66,7 +67,7 @@ public class QueryStringDecoder {
* Creates a new decoder that decodes the specified URI encoded in the
* specified charset.
*/
public QueryStringDecoder(String uri, String charset) {
public QueryStringDecoder(String uri, Charset charset) {
if (uri == null) {
throw new NullPointerException("uri");
}
@ -78,6 +79,14 @@ public class QueryStringDecoder {
this.charset = charset;
}
/**
* @deprecated Use {@link #QueryStringDecoder(String, Charset)} instead.
*/
@Deprecated
public QueryStringDecoder(String uri, String charset) {
this(uri, Charset.forName(charset));
}
/**
* Creates a new decoder that decodes the specified URI. The decoder will
* assume that the query string is encoded in UTF-8.
@ -90,7 +99,7 @@ public class QueryStringDecoder {
* Creates a new decoder that decodes the specified URI encoded in the
* specified charset.
*/
public QueryStringDecoder(URI uri, String charset){
public QueryStringDecoder(URI uri, Charset charset){
if (uri == null) {
throw new NullPointerException("uri");
}
@ -102,6 +111,14 @@ public class QueryStringDecoder {
this.charset = charset;
}
/**
* @deprecated Use {@link #QueryStringDecoder(URI, Charset)} instead.
*/
@Deprecated
public QueryStringDecoder(URI uri, String charset){
this(uri, Charset.forName(charset));
}
/**
* Returns the decoded path string of the URI.
*/
@ -160,15 +177,15 @@ public class QueryStringDecoder {
}
}
private static String decodeComponent(String s, String charset) {
private static String decodeComponent(String s, Charset charset) {
if (s == null) {
return "";
}
try {
return URLDecoder.decode(s, charset);
return URLDecoder.decode(s, charset.name());
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException(charset);
throw new UnsupportedCharsetException(charset.name());
}
}
}

View File

@ -19,6 +19,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.List;
@ -45,7 +46,7 @@ import java.util.List;
*/
public class QueryStringEncoder {
private final String charset;
private final Charset charset;
private final String uri;
private final List<Param> params = new ArrayList<Param>();
@ -61,7 +62,7 @@ public class QueryStringEncoder {
* Creates a new encoder that encodes a URI that starts with the specified
* path string in the specified charset.
*/
public QueryStringEncoder(String uri, String charset) {
public QueryStringEncoder(String uri, Charset charset) {
if (uri == null) {
throw new NullPointerException("uri");
}
@ -73,6 +74,14 @@ public class QueryStringEncoder {
this.charset = charset;
}
/**
* @deprecated Use {@link #QueryStringEncoder(String, Charset)} instead.
*/
@Deprecated
public QueryStringEncoder(String uri, String charset) {
this(uri, Charset.forName(charset));
}
/**
* Adds a parameter with the specified name and value to this encoder.
*/
@ -119,11 +128,11 @@ public class QueryStringEncoder {
}
}
private static String encodeComponent(String s, String charset) {
private static String encodeComponent(String s, Charset charset) {
try {
return URLEncoder.encode(s, charset).replaceAll("\\+", "%20");
return URLEncoder.encode(s, charset.name()).replaceAll("\\+", "%20");
} catch (UnsupportedEncodingException e) {
throw new UnsupportedCharsetException(charset);
throw new UnsupportedCharsetException(charset.name());
}
}

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferFactory;
@ -504,11 +505,34 @@ class ReplayingDecoderBuffer implements ChannelBuffer {
return buffer.toByteBuffers(index, length);
}
public String toString(int index, int length, Charset charset) {
checkIndex(index, length);
return buffer.toString(index, length, charset);
}
public String toString(
int index, int length, Charset charset,
ChannelBufferIndexFinder terminatorFinder) {
checkIndex(index, length);
return buffer.toString(index, length, charset, terminatorFinder);
}
public String toString(Charset charsetName) {
throw new UnreplayableOperationException();
}
public String toString(
Charset charset, ChannelBufferIndexFinder terminatorFinder) {
throw new UnreplayableOperationException();
}
@Deprecated
public String toString(int index, int length, String charsetName) {
checkIndex(index, length);
return buffer.toString(index, length, charsetName);
}
@Deprecated
public String toString(
int index, int length, String charsetName,
ChannelBufferIndexFinder terminatorFinder) {
@ -516,10 +540,12 @@ class ReplayingDecoderBuffer implements ChannelBuffer {
return buffer.toString(index, length, charsetName, terminatorFinder);
}
@Deprecated
public String toString(String charsetName) {
throw new UnreplayableOperationException();
}
@Deprecated
public String toString(
String charsetName, ChannelBufferIndexFinder terminatorFinder) {
throw new UnreplayableOperationException();

View File

@ -38,10 +38,10 @@ import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
*
* // Decoders
* pipeline.addLast("frameDecoder", new {@link DelimiterBasedFrameDecoder}(80, {@link Delimiters#lineDelimiter()}));
* pipeline.addLast("stringDecoder", new {@link StringDecoder}("UTF-8"));
* pipeline.addLast("stringDecoder", new {@link StringDecoder}(CharsetUtil.UTF_8));
*
* // Encoder
* pipeline.addLast("stringEncoder", new {@link StringEncoder}("UTF-8"));
* pipeline.addLast("stringEncoder", new {@link StringEncoder}(CharsetUtil.UTF_8));
* </pre>
* and then you can use a {@link String} instead of a {@link ChannelBuffer}
* as a message:
@ -62,7 +62,8 @@ import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
@ChannelPipelineCoverage("all")
public class StringDecoder extends OneToOneDecoder {
private final String charsetName;
// TODO Use CharsetDecoder instead.
private final Charset charset;
/**
* Creates a new instance with the current system character set.
@ -72,24 +73,21 @@ public class StringDecoder extends OneToOneDecoder {
}
/**
* Creates a new instance.
*
* @param charsetName the name of the character set to use for decoding
*/
public StringDecoder(String charsetName) {
this(Charset.forName(charsetName));
}
/**
* Creates a new instance.
*
* @param charset the character set to use for decoding
* Creates a new instance with the specified character set.
*/
public StringDecoder(Charset charset) {
if (charset == null) {
throw new NullPointerException("charset");
}
charsetName = charset.name();
this.charset = charset;
}
/**
* @deprecated Use {@link #StringDecoder(Charset)} instead.
*/
@Deprecated
public StringDecoder(String charsetName) {
this(Charset.forName(charsetName));
}
@Override
@ -98,6 +96,6 @@ public class StringDecoder extends OneToOneDecoder {
if (!(msg instanceof ChannelBuffer)) {
return msg;
}
return ((ChannelBuffer) msg).toString(charsetName);
return ((ChannelBuffer) msg).toString(charset);
}
}

View File

@ -36,10 +36,10 @@ import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
*
* // Decoders
* pipeline.addLast("frameDecoder", new {@link DelimiterBasedFrameDecoder}({@link Delimiters#lineDelimiter()}));
* pipeline.addLast("stringDecoder", new {@link StringDecoder}("UTF-8"));
* pipeline.addLast("stringDecoder", new {@link StringDecoder}(CharsetUtil.UTF_8));
*
* // Encoder
* pipeline.addLast("stringEncoder", new {@link StringEncoder}("UTF-8"));
* pipeline.addLast("stringEncoder", new {@link StringEncoder}(CharsetUtil.UTF_8));
* </pre>
* and then you can use a {@link String} instead of a {@link ChannelBuffer}
* as a message:
@ -60,7 +60,8 @@ import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
@ChannelPipelineCoverage("all")
public class StringEncoder extends OneToOneEncoder {
private final String charsetName;
// TODO Use CharsetEncoder instead.
private final Charset charset;
/**
* Creates a new instance with the current system character set.
@ -69,15 +70,22 @@ public class StringEncoder extends OneToOneEncoder {
this(Charset.defaultCharset());
}
public StringEncoder(String charsetName) {
this(Charset.forName(charsetName));
}
/**
* Creates a new instance with the specified character set.
*/
public StringEncoder(Charset charset) {
if (charset == null) {
throw new NullPointerException("charset");
}
charsetName = charset.name();
this.charset = charset;
}
/**
* @deprecated Use {@link #StringEncoder(Charset)} instead.
*/
@Deprecated
public StringEncoder(String charsetName) {
this(Charset.forName(charsetName));
}
@Override
@ -86,6 +94,6 @@ public class StringEncoder extends OneToOneEncoder {
if (!(msg instanceof String)) {
return msg;
}
return copiedBuffer((String) msg, charsetName);
return copiedBuffer((String) msg, charset);
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright 2009 Red Hat, Inc.
*
* Red Hat 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.jboss.netty.util;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.util.IdentityHashMap;
import java.util.Map;
/**
* A utility class that provides various common operations and constants
* related with {@link Charset} and its relevant classes.
*
* @author The Netty Project (netty-dev@lists.jboss.org)
* @author Trustin Lee (trustin@gmail.com)
* @version $Rev$, $Date$
*/
public class CharsetUtil {
/**
* 16-bit UTF (UCS Transformation Format) whose byte order is identified by
* an optional byte-order mark
*/
public static final Charset UTF_16 = Charset.forName("UTF-16");
/**
* 16-bit UTF (UCS Transformation Format) whose byte order is big-endian
*/
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
/**
* 16-bit UTF (UCS Transformation Format) whose byte order is little-endian
*/
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
/**
* 8-bit UTF (UCS Transformation Format)
*/
public static final Charset UTF_8 = Charset.forName("UTF-8");
/**
* ISO Latin Alphabet No. 1, as known as <tt>ISO-LATIN-1</tt>
*/
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
/**
* 7-bit ASCII, as known as ISO646-US or the Basic Latin block of the
* Unicode character set
*/
public static final Charset US_ASCII = Charset.forName("US-ASCII");
private static final ThreadLocal<Map<Charset, CharsetEncoder>> encoders =
new ThreadLocal<Map<Charset,CharsetEncoder>>() {
@Override
protected Map<Charset, CharsetEncoder> initialValue() {
return new IdentityHashMap<Charset, CharsetEncoder>();
}
};
private static final ThreadLocal<Map<Charset, CharsetDecoder>> decoders =
new ThreadLocal<Map<Charset,CharsetDecoder>>() {
@Override
protected Map<Charset, CharsetDecoder> initialValue() {
return new IdentityHashMap<Charset, CharsetDecoder>();
}
};
/**
* Returns a cached thread-local {@link CharsetEncoder} for the specified
* <tt>charset</tt>.
*/
public static CharsetEncoder getEncoder(String charset) {
if (charset == null) {
throw new NullPointerException("charset");
}
return getEncoder(Charset.forName(charset));
}
/**
* Returns a cached thread-local {@link CharsetEncoder} for the specified
* <tt>charset</tt>.
*/
public static CharsetEncoder getEncoder(Charset charset) {
if (charset == null) {
throw new NullPointerException("charset");
}
Map<Charset, CharsetEncoder> map = encoders.get();
CharsetEncoder e = map.get(charset);
if (e != null) {
e.reset();
e.onMalformedInput(CodingErrorAction.REPLACE);
e.onUnmappableCharacter(CodingErrorAction.REPLACE);
return e;
}
e = charset.newEncoder();
e.onMalformedInput(CodingErrorAction.REPLACE);
e.onUnmappableCharacter(CodingErrorAction.REPLACE);
map.put(charset, e);
return e;
}
/**
* Returns a cached thread-local {@link CharsetDecoder} for the specified
* <tt>charset</tt>.
*/
public static CharsetDecoder getDecoder(String charset) {
if (charset == null) {
throw new NullPointerException("charset");
}
return getDecoder(Charset.forName(charset));
}
/**
* Returns a cached thread-local {@link CharsetDecoder} for the specified
* <tt>charset</tt>.
*/
public static CharsetDecoder getDecoder(Charset charset) {
if (charset == null) {
throw new NullPointerException("charset");
}
Map<Charset, CharsetDecoder> map = decoders.get();
CharsetDecoder d = map.get(charset);
if (d != null) {
d.reset();
d.onMalformedInput(CodingErrorAction.REPLACE);
d.onUnmappableCharacter(CodingErrorAction.REPLACE);
return d;
}
d = charset.newDecoder();
d.onMalformedInput(CodingErrorAction.REPLACE);
d.onUnmappableCharacter(CodingErrorAction.REPLACE);
map.put(charset, d);
return d;
}
private CharsetUtil() {
// Unused
}
}

View File

@ -28,6 +28,7 @@ import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Set;
import org.jboss.netty.util.CharsetUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -1542,17 +1543,17 @@ public abstract class AbstractChannelBufferTest {
}
buffer.clear();
buffer.writeBytes(copiedBuffer("Hello, World!", "ISO-8859-1"));
assertEquals("Hello, World!", buffer.toString("ISO-8859-1"));
buffer.writeBytes(copiedBuffer("Hello, World!", CharsetUtil.ISO_8859_1));
assertEquals("Hello, World!", buffer.toString(CharsetUtil.ISO_8859_1));
// Same with the previous one
assertEquals("Hello, World!", buffer.toString("ISO-8859-1", null));
assertEquals("Hello, World!", buffer.toString(CharsetUtil.ISO_8859_1, null));
// NUL not found.
assertEquals("Hello, World!", buffer.toString("ISO-8859-1", ChannelBufferIndexFinder.NUL));
assertEquals("Hello, World!", buffer.toString(CharsetUtil.ISO_8859_1, ChannelBufferIndexFinder.NUL));
// Linear space found.
assertEquals("Hello,", buffer.toString("ISO-8859-1", ChannelBufferIndexFinder.LINEAR_WHITESPACE));
assertEquals("Hello,", buffer.toString(CharsetUtil.ISO_8859_1, ChannelBufferIndexFinder.LINEAR_WHITESPACE));
}
@Test

View File

@ -17,6 +17,7 @@ package org.jboss.netty.buffer;
import static org.junit.Assert.*;
import org.jboss.netty.util.CharsetUtil;
import org.junit.Test;
@ -32,7 +33,8 @@ public class ChannelBufferIndexFinderTest {
@Test
public void testForward() {
ChannelBuffer buf = ChannelBuffers.copiedBuffer(
"abc\r\n\ndef\r\rghi\n\njkl\0\0mno \t\tx", "ISO-8859-1");
"abc\r\n\ndef\r\rghi\n\njkl\0\0mno \t\tx",
CharsetUtil.ISO_8859_1);
assertEquals(3, buf.indexOf(Integer.MIN_VALUE, buf.capacity(), ChannelBufferIndexFinder.CRLF));
assertEquals(6, buf.indexOf(3, buf.capacity(), ChannelBufferIndexFinder.NOT_CRLF));
@ -50,7 +52,8 @@ public class ChannelBufferIndexFinderTest {
@Test
public void testBackward() {
ChannelBuffer buf = ChannelBuffers.copiedBuffer(
"abc\r\n\ndef\r\rghi\n\njkl\0\0mno \t\tx", "ISO-8859-1");
"abc\r\n\ndef\r\rghi\n\njkl\0\0mno \t\tx",
CharsetUtil.ISO_8859_1);
assertEquals(27, buf.indexOf(Integer.MAX_VALUE, 0, ChannelBufferIndexFinder.LINEAR_WHITESPACE));
assertEquals(23, buf.indexOf(28, 0, ChannelBufferIndexFinder.NOT_LINEAR_WHITESPACE));

View File

@ -26,6 +26,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import org.jboss.netty.util.CharsetUtil;
import org.junit.Test;
/**
@ -97,8 +98,8 @@ public class ReadOnlyChannelBufferTest {
expect(buf.toByteBuffer(23, 24)).andReturn(bb);
expect(buf.toByteBuffers(25, 26)).andReturn(bbs);
expect(buf.toString(27, 28, "29")).andReturn("30");
expect(buf.capacity()).andReturn(31);
expect(buf.toString(27, 28, CharsetUtil.UTF_8)).andReturn("29");
expect(buf.capacity()).andReturn(30);
replay(buf);
@ -125,8 +126,8 @@ public class ReadOnlyChannelBufferTest {
assertEquals(102, roBBs[1].capacity());
assertTrue(roBBs[1].isReadOnly());
assertEquals("30", roBuf.toString(27, 28, "29"));
assertEquals(31, roBuf.capacity());
assertEquals("29", roBuf.toString(27, 28, CharsetUtil.UTF_8));
assertEquals(30, roBuf.capacity());
verify(buf);
}

View File

@ -38,6 +38,7 @@ import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.util.CharsetUtil;
import org.jboss.netty.util.TestUtil;
import org.jboss.netty.util.internal.ExecutorUtil;
import org.junit.AfterClass;
@ -93,13 +94,13 @@ public abstract class AbstractSocketStringEchoTest {
EchoHandler ch = new EchoHandler();
sb.getPipeline().addLast("framer", new DelimiterBasedFrameDecoder(512, Delimiters.lineDelimiter()));
sb.getPipeline().addLast("decoder", new StringDecoder("ISO-8859-1"));
sb.getPipeline().addBefore("decoder", "encoder", new StringEncoder("ISO-8859-1"));
sb.getPipeline().addLast("decoder", new StringDecoder(CharsetUtil.ISO_8859_1));
sb.getPipeline().addBefore("decoder", "encoder", new StringEncoder(CharsetUtil.ISO_8859_1));
sb.getPipeline().addAfter("decoder", "handler", sh);
cb.getPipeline().addLast("framer", new DelimiterBasedFrameDecoder(512, Delimiters.lineDelimiter()));
cb.getPipeline().addLast("decoder", new StringDecoder("ISO-8859-1"));
cb.getPipeline().addBefore("decoder", "encoder", new StringEncoder("ISO-8859-1"));
cb.getPipeline().addLast("decoder", new StringDecoder(CharsetUtil.ISO_8859_1));
cb.getPipeline().addBefore("decoder", "encoder", new StringEncoder(CharsetUtil.ISO_8859_1));
cb.getPipeline().addAfter("decoder", "handler", ch);
Channel sc = sb.bind(new InetSocketAddress(0));