use of java.nio.charset.CoderResult in project bson4jackson by michel-kraemer.
the class LittleEndianInputStream method readUTF.
/**
* Reads a modified UTF-8 string from a DataInput object
* @param input the DataInput object to read from
* @param len the number of bytes to read (please do not mix that up
* with the number of characters!). If this is -1 then the method
* will read bytes until the first one is zero (0x00). The zero
* byte will not be included in the result string.
* @return the UTF-8 string
* @throws IOException if an I/O error occurs
* @throws CharacterCodingException if an invalid UTF-8 character
* has been read
*/
public String readUTF(DataInput input, int len) throws IOException {
StaticBuffers staticBuffers = StaticBuffers.getInstance();
ByteBuffer utf8buf = staticBuffers.byteBuffer(UTF8_BUFFER, 1024 * 8);
byte[] rawUtf8Buf = utf8buf.array();
CharsetDecoder dec = Charset.forName("UTF-8").newDecoder();
int expectedLen = (len > 0 ? (int) (dec.averageCharsPerByte() * len) + 1 : 1024);
CharBuffer cb = staticBuffers.charBuffer(UTF8_BUFFER, expectedLen);
try {
while (len != 0 || utf8buf.position() > 0) {
// read as much as possible
if (len < 0) {
// read until the first zero byte
while (utf8buf.remaining() > 0) {
byte b = input.readByte();
if (b == 0) {
len = 0;
break;
}
utf8buf.put(b);
}
utf8buf.flip();
} else if (len > 0) {
int r = Math.min(len, utf8buf.remaining());
input.readFully(rawUtf8Buf, utf8buf.position(), r);
len -= r;
utf8buf.limit(utf8buf.position() + r);
utf8buf.rewind();
} else {
utf8buf.flip();
}
// decode byte buffer
CoderResult cr = dec.decode(utf8buf, cb, len == 0);
if (cr.isUnderflow()) {
// too few input bytes. move rest of the buffer
// to the beginning and then try again
utf8buf.compact();
} else if (cr.isOverflow()) {
// output buffer to small. enlarge buffer and try again
utf8buf.compact();
// create a new char buffer with the same key
CharBuffer newBuf = staticBuffers.charBuffer(UTF8_BUFFER, cb.capacity() + 1024);
cb.flip();
newBuf.put(cb);
cb = newBuf;
} else if (cr.isError()) {
cr.throwException();
}
}
} finally {
staticBuffers.releaseCharBuffer(UTF8_BUFFER, cb);
staticBuffers.releaseByteBuffer(UTF8_BUFFER, utf8buf);
}
cb.flip();
return cb.toString();
}
use of java.nio.charset.CoderResult in project BiglyBT by BiglySoftware.
the class LocaleUtilDecoderReal method tryDecode.
@Override
public String tryDecode(byte[] array, boolean lax) {
try {
ByteBuffer bb = ByteBuffer.wrap(array);
CharBuffer cb = CharBuffer.allocate(array.length);
CoderResult cr;
this_mon.enter();
try {
cr = decoder.decode(bb, cb, true);
} finally {
this_mon.exit();
}
if (!cr.isError()) {
cb.flip();
String str = cb.toString();
if (lax) {
return (str);
}
byte[] b2 = str.getBytes(getName());
if (Arrays.equals(array, b2)) {
return (str);
}
}
return (null);
} catch (Throwable e) {
return (null);
}
}
use of java.nio.charset.CoderResult in project tomcat70 by apache.
the class WsFrameBase method processDataText.
private boolean processDataText() throws IOException {
// Copy the available data to the buffer
TransformationResult tr = transformation.getMoreData(opCode, fin, rsv, messageBufferBinary);
while (!TransformationResult.END_OF_FRAME.equals(tr)) {
// Frame not complete - we ran out of something
// Convert bytes to UTF-8
messageBufferBinary.flip();
while (true) {
CoderResult cr = utf8DecoderMessage.decode(messageBufferBinary, messageBufferText, false);
if (cr.isError()) {
throw new WsIOException(new CloseReason(CloseCodes.NOT_CONSISTENT, sm.getString("wsFrame.invalidUtf8")));
} else if (cr.isOverflow()) {
// Ran out of space in text buffer - flush it
if (usePartial()) {
messageBufferText.flip();
sendMessageText(false);
messageBufferText.clear();
} else {
throw new WsIOException(new CloseReason(CloseCodes.TOO_BIG, sm.getString("wsFrame.textMessageTooBig")));
}
} else if (cr.isUnderflow()) {
// Compact what we have to create as much space as possible
messageBufferBinary.compact();
// What did we run out of?
if (TransformationResult.OVERFLOW.equals(tr)) {
// refill
break;
} else {
// Ran out of input data - get some more
return false;
}
}
}
// Read more input data
tr = transformation.getMoreData(opCode, fin, rsv, messageBufferBinary);
}
messageBufferBinary.flip();
boolean last = false;
// Convert bytes to UTF-8
while (true) {
CoderResult cr = utf8DecoderMessage.decode(messageBufferBinary, messageBufferText, last);
if (cr.isError()) {
throw new WsIOException(new CloseReason(CloseCodes.NOT_CONSISTENT, sm.getString("wsFrame.invalidUtf8")));
} else if (cr.isOverflow()) {
// Ran out of space in text buffer - flush it
if (usePartial()) {
messageBufferText.flip();
sendMessageText(false);
messageBufferText.clear();
} else {
throw new WsIOException(new CloseReason(CloseCodes.TOO_BIG, sm.getString("wsFrame.textMessageTooBig")));
}
} else if (cr.isUnderflow() && !last) {
if (continuationExpected) {
// managed to decode
if (usePartial()) {
messageBufferText.flip();
sendMessageText(false);
messageBufferText.clear();
}
messageBufferBinary.compact();
newFrame();
// Process next frame
return true;
} else {
// Make sure coder has flushed all output
last = true;
}
} else {
// End of message
messageBufferText.flip();
sendMessageText(true);
newMessage();
return true;
}
}
}
use of java.nio.charset.CoderResult in project tomcat70 by apache.
the class WsFrameBase method processDataControl.
private boolean processDataControl() throws IOException {
TransformationResult tr = transformation.getMoreData(opCode, fin, rsv, controlBufferBinary);
if (TransformationResult.UNDERFLOW.equals(tr)) {
return false;
}
// Control messages have fixed message size so
// TransformationResult.OVERFLOW is not possible here
controlBufferBinary.flip();
if (opCode == Constants.OPCODE_CLOSE) {
open = false;
String reason = null;
int code = CloseCodes.NORMAL_CLOSURE.getCode();
if (controlBufferBinary.remaining() == 1) {
controlBufferBinary.clear();
// Payload must be zero or greater than 2
throw new WsIOException(new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.oneByteCloseCode")));
}
if (controlBufferBinary.remaining() > 1) {
code = controlBufferBinary.getShort();
if (controlBufferBinary.remaining() > 0) {
CoderResult cr = utf8DecoderControl.decode(controlBufferBinary, controlBufferText, true);
if (cr.isError()) {
controlBufferBinary.clear();
controlBufferText.clear();
throw new WsIOException(new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.invalidUtf8Close")));
}
// There will be no overflow as the output buffer is big
// enough. There will be no underflow as all the data is
// passed to the decoder in a single call.
controlBufferText.flip();
reason = controlBufferText.toString();
}
}
wsSession.onClose(new CloseReason(Util.getCloseCode(code), reason));
} else if (opCode == Constants.OPCODE_PING) {
if (wsSession.isOpen()) {
wsSession.getBasicRemote().sendPong(controlBufferBinary);
}
} else if (opCode == Constants.OPCODE_PONG) {
MessageHandler.Whole<PongMessage> mhPong = wsSession.getPongMessageHandler();
if (mhPong != null) {
try {
mhPong.onMessage(new WsPongMessage(controlBufferBinary));
} catch (Throwable t) {
handleThrowableOnSend(t);
} finally {
controlBufferBinary.clear();
}
}
} else {
// Should have caught this earlier but just in case...
controlBufferBinary.clear();
throw new WsIOException(new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.invalidOpCode", Integer.valueOf(opCode))));
}
controlBufferBinary.clear();
newFrame();
return true;
}
use of java.nio.charset.CoderResult in project tomcat70 by apache.
the class B2CConverter method convert.
/**
* Convert the given bytes to characters.
*
* @param bc byte input
* @param cc char output
* @param endOfInput Is this all of the available data
*/
public void convert(ByteChunk bc, CharChunk cc, boolean endOfInput) throws IOException {
if ((bb == null) || (bb.array() != bc.getBuffer())) {
// Create a new byte buffer if anything changed
bb = ByteBuffer.wrap(bc.getBuffer(), bc.getStart(), bc.getLength());
} else {
// Initialize the byte buffer
bb.limit(bc.getEnd());
bb.position(bc.getStart());
}
if ((cb == null) || (cb.array() != cc.getBuffer())) {
// Create a new char buffer if anything changed
cb = CharBuffer.wrap(cc.getBuffer(), cc.getEnd(), cc.getBuffer().length - cc.getEnd());
} else {
// Initialize the char buffer
cb.limit(cc.getBuffer().length);
cb.position(cc.getEnd());
}
CoderResult result = null;
// Parse leftover if any are present
if (leftovers.position() > 0) {
int pos = cb.position();
// Loop until one char is decoded or there is a decoder error
do {
leftovers.put(bc.substractB());
leftovers.flip();
result = decoder.decode(leftovers, cb, endOfInput);
leftovers.position(leftovers.limit());
leftovers.limit(leftovers.array().length);
} while (result.isUnderflow() && (cb.position() == pos));
if (result.isError() || result.isMalformed()) {
result.throwException();
}
bb.position(bc.getStart());
leftovers.position(0);
}
// Do the decoding and get the results into the byte chunk and the char
// chunk
result = decoder.decode(bb, cb, endOfInput);
if (result.isError() || result.isMalformed()) {
result.throwException();
} else if (result.isOverflow()) {
// Propagate current positions to the byte chunk and char chunk, if
// this continues the char buffer will get resized
bc.setOffset(bb.position());
cc.setEnd(cb.position());
} else if (result.isUnderflow()) {
// Propagate current positions to the byte chunk and char chunk
bc.setOffset(bb.position());
cc.setEnd(cb.position());
// Put leftovers in the leftovers byte buffer
if (bc.getLength() > 0) {
leftovers.limit(leftovers.array().length);
leftovers.position(bc.getLength());
bc.substract(leftovers.array(), 0, bc.getLength());
}
}
}
Aggregations