[#1906] Use a ByteBuf allocator from the ByteBufAllocator when encode Strings

This commit is contained in:
Norman Maurer 2013-10-09 21:18:08 +02:00
parent 136e1ebba8
commit 522dbf8543
4 changed files with 61 additions and 13 deletions

View File

@ -304,24 +304,36 @@ public final class ByteBufUtil {
return -1;
}
static ByteBuffer encodeString(CharBuffer src, Charset charset) {
/**
* Encode the given {@link CharBuffer} using the given {@link Charset} into a new {@link ByteBuf} which
* is allocated via the {@link ByteBufAllocator}.
*/
public static ByteBuf encodeString(ByteBufAllocator alloc, CharBuffer src, Charset charset) {
final CharsetEncoder encoder = CharsetUtil.getEncoder(charset);
final ByteBuffer dst = ByteBuffer.allocate(
(int) ((double) src.remaining() * encoder.maxBytesPerChar()));
int length = (int) ((double) src.remaining() * encoder.maxBytesPerChar());
boolean release = true;
final ByteBuf dst = alloc.buffer(length);
try {
CoderResult cr = encoder.encode(src, dst, true);
final ByteBuffer dstBuf = dst.internalNioBuffer(0, length);
final int pos = dstBuf.position();
CoderResult cr = encoder.encode(src, dstBuf, true);
if (!cr.isUnderflow()) {
cr.throwException();
}
cr = encoder.flush(dst);
cr = encoder.flush(dstBuf);
if (!cr.isUnderflow()) {
cr.throwException();
}
dst.writerIndex(dst.writerIndex() + (dstBuf.position() - pos));
release = false;
return dst;
} catch (CharacterCodingException x) {
throw new IllegalStateException(x);
} finally {
if (release) {
dst.release();
}
}
dst.flip();
return dst;
}
static String decodeString(ByteBuffer src, Charset charset) {

View File

@ -647,10 +647,7 @@ public final class Unpooled {
}
private static ByteBuf copiedBuffer(CharBuffer buffer, Charset charset) {
ByteBuffer dst = ByteBufUtil.encodeString(buffer, charset);
ByteBuf result = wrappedBuffer(dst.array());
result.writerIndex(dst.remaining());
return result;
return ByteBufUtil.encodeString(ALLOC, buffer, charset);
}
/**

View File

@ -16,13 +16,14 @@
package io.netty.handler.codec.string;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.List;
@ -76,6 +77,6 @@ public class StringEncoder extends MessageToMessageEncoder<CharSequence> {
return;
}
out.add(Unpooled.copiedBuffer(msg, charset));
out.add(ByteBufUtil.encodeString(ctx.alloc(), CharBuffer.wrap(msg), charset));
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2014 The Netty Project
*
* The Netty Project 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 io.netty.handler.codec.string;
import io.netty.buffer.ByteBuf;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.util.CharsetUtil;
import org.junit.Assert;
import org.junit.Test;
public class StringEncoderTest {
@Test
public void testEncode() {
String msg = "Test";
EmbeddedChannel channel = new EmbeddedChannel(new StringEncoder());
Assert.assertTrue(channel.writeOutbound(msg));
Assert.assertTrue(channel.finish());
ByteBuf buf = (ByteBuf) channel.readOutbound();
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
Assert.assertArrayEquals(msg.getBytes(CharsetUtil.UTF_8), data);
Assert.assertNull(channel.readOutbound());
}
}