下面列出了怎么用java.nio.CharBuffer的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Convert the chars to bytes, then send the data to the client.
*
* @param from Char buffer to be written to the response
*
* @throws IOException An underlying IOException occurred
*/
public void realWriteChars(CharBuffer from) throws IOException {
while (from.remaining() > 0) {
conv.convert(from, bb);
if (bb.remaining() == 0) {
// Break out of the loop if more chars are needed to produce any output
break;
}
if (from.remaining() > 0) {
flushByteBuffer();
} else if (conv.isUndeflow() && bb.limit() > bb.capacity() - 4) {
// Handle an edge case. There are no more chars to write at the
// moment but there is a leftover character in the converter
// which must be part of a surrogate pair. The byte buffer does
// not have enough space left to output the bytes for this pair
// once it is complete )it will require 4 bytes) so flush now to
// prevent the bytes for the leftover char and the rest of the
// surrogate pair yet to be written from being lost.
// See TestOutputBuffer#testUtf8SurrogateBody()
flushByteBuffer();
}
}
}
/** If the argument string does not contain non-ASCII characters, returns the string itself;
* otherwise, encodes non-ASCII characters by %XX-encoded UTF-8 sequences.
*
* @param s a string.
* @return <code>c</code> with non-ASCII characters replaced by %XX-encoded UTF-8 sequences.
*/
private static String sanitize(final String s) {
int i = s.length();
for(i = s.length(); i-- != 0;) if (s.charAt(i) >= (char)128) break;
if (i == -1) return s;
final ByteBuffer byteBuffer = Charsets.UTF_8.encode(CharBuffer.wrap(s));
final StringBuilder stringBuilder = new StringBuilder();
while (byteBuffer.hasRemaining()) {
final int b = byteBuffer.get() & 0xff;
if (b >= 0x80) stringBuilder.append('%').append(HEX_DIGIT[b >> 4 & 0xf]).append(HEX_DIGIT[b & 0xf]);
else stringBuilder.append((char)b);
}
return stringBuilder.toString();
}
@Override
public boolean test(Readable readable) {
CharBuffer buf = CharBuffer.allocate(100);
try {
int n = readable.read(buf);
if (n < 0) {
return false;
}
buf.flip();
for (int i = 0; i < n; ++i) {
char c = buf.charAt(i);
if (Character.isISOControl(c)) {
if (c != '\n' && c != '\r') {
return true;
}
}
}
return false;
} catch (IOException e) {
throw E.ioException(e);
} finally {
buf.clear();
}
}
@Override
public Mono<Resource> transform(ServerWebExchange exchange, Resource inputResource,
ResourceTransformerChain chain) {
return chain.transform(exchange, inputResource)
.flatMap(outputResource -> {
String name = outputResource.getFilename();
if (!this.fileExtension.equals(StringUtils.getFilenameExtension(name))) {
return Mono.just(outputResource);
}
DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory();
Flux<DataBuffer> flux = DataBufferUtils
.read(outputResource, bufferFactory, StreamUtils.BUFFER_SIZE);
return DataBufferUtils.join(flux)
.flatMap(dataBuffer -> {
CharBuffer charBuffer = DEFAULT_CHARSET.decode(dataBuffer.asByteBuffer());
DataBufferUtils.release(dataBuffer);
String content = charBuffer.toString();
return transform(content, outputResource, chain, exchange);
});
});
}
/**
* Parses a UCS-4 character from the given source buffer, handling
* surrogates.
*
* @param c The first character
* @param in The source buffer, from which one more character
* will be consumed if c is a high surrogate
*
* @returns Either a parsed UCS-4 character, in which case the isPair()
* and increment() methods will return meaningful values, or
* -1, in which case error() will return a descriptive result
* object
*/
public int parse(char c, CharBuffer in) {
if (Surrogate.isHigh(c)) {
if (!in.hasRemaining()) {
error = CoderResult.UNDERFLOW;
return -1;
}
char d = in.get();
if (Surrogate.isLow(d)) {
character = toUCS4(c, d);
isPair = true;
error = null;
return character;
}
error = CoderResult.malformedForLength(1);
return -1;
}
if (Surrogate.isLow(c)) {
error = CoderResult.malformedForLength(1);
return -1;
}
character = c;
isPair = false;
error = null;
return character;
}
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
int mark = src.position();
try {
while (src.hasRemaining()) {
char c = src.get();
int b = encode(c);
if (b == UNMAPPABLE_ENCODING) {
if (Character.isSurrogate(c)) {
if (sgp == null)
sgp = new Surrogate.Parser();
if (sgp.parse(c, src) < 0)
return sgp.error();
return sgp.unmappableResult();
}
return CoderResult.unmappableForLength(1);
}
if (!dst.hasRemaining())
return CoderResult.OVERFLOW;
dst.put((byte)b);
mark++;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(mark);
}
}
String toString(byte[] ba, int length) {
CharsetDecoder cd = decoder().reset();
int len = (int)(length * cd.maxCharsPerByte());
char[] ca = new char[len];
if (len == 0)
return new String(ca);
// UTF-8 only for now. Other ArrayDeocder only handles
// CodingErrorAction.REPLACE mode. ZipCoder uses
// REPORT mode.
if (isUTF8 && cd instanceof ArrayDecoder) {
int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);
if (clen == -1) // malformed
throw new IllegalArgumentException("MALFORMED");
return new String(ca, 0, clen);
}
ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
CharBuffer cb = CharBuffer.wrap(ca);
CoderResult cr = cd.decode(bb, cb, true);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
cr = cd.flush(cb);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
return new String(ca, 0, cb.position());
}
private void connect(final Readable source, final Appendable sink) {
Thread thread = new Thread(new Runnable() {
public void run() {
CharBuffer cb = CharBuffer.wrap(new char [256]);
try {
while (source.read(cb) != -1) {
cb.flip();
sink.append(cb);
cb.clear();
}
if (sink instanceof Flushable) {
((Flushable)sink).flush();
}
} catch (IOException e) { /* prolly broken pipe, just die */ }
}
});
thread.setDaemon(true);
thread.start();
}
public static void testCharSequence() throws Exception {
for (int i=0; i<ITERATIONS; i++) {
int length = rnd.nextInt(STR_LEN) + 1;
StringBuilder testStringBuilder = new StringBuilder();
for(int x=0; x<length; x++) {
char aChar = (char)rnd.nextInt();
testStringBuilder.append(aChar);
}
String testString = testStringBuilder.toString();
char c = testStringBuilder.charAt(0);
testStringBuilder.setCharAt(0, 'c');
testStringBuilder.setCharAt(0, c);
CharBuffer buf = CharBuffer.wrap(testStringBuilder.toString());
if (!testString.contentEquals(buf))
throw new RuntimeException("ContentsEqual failure");
}
}
private CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
int mark = src.position();
try {
while (src.hasRemaining()) {
char c = decode(src.get());
if (c == UNMAPPABLE_DECODING)
return CoderResult.unmappableForLength(1);
if (!dst.hasRemaining())
return CoderResult.OVERFLOW;
dst.put(c);
mark++;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(mark);
}
}
/**
* Create instance for specified charset.
* @param charset
*/
public FixLenCharDataParser(DataRecordMetadata metadata, String charset) {
super(metadata, charset);
this.metadata = metadata;
charBuffer = CharBuffer.allocate(Defaults.DEFAULT_INTERNAL_IO_BUFFER_SIZE);
setRecordDelimiters(null);
}
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
try {
while (sp < sl) {
char c = sa[sp];
if ( c > '\u007f'&& c < '\uFFFE') {
int nb = toEUC(c, bb);
if (nb != -1) {
int p = 0;
if (nb == 4)
p = (bb[1] & 0xff) - 0xa0;
if (p == plane) {
if (dl - dp < 2)
return CoderResult.OVERFLOW;
if (nb == 2) {
da[dp++] = (byte)(bb[0] & 0x7f);
da[dp++] = (byte)(bb[1] & 0x7f);
} else {
da[dp++] = (byte)(bb[2] & 0x7f);
da[dp++] = (byte)(bb[3] & 0x7f);
}
sp++;
continue;
}
}
}
return CoderResult.unmappableForLength(1);
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) {
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
sp = (sp <= sl ? sp : sl);
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
dp = (dp <= dl ? dp : dl);
try {
while (sp < sl) {
char c = sa[sp];
if (Surrogate.is(c)) {
if (sgp.parse(c, sa, sp, sl) < 0)
return sgp.error();
return sgp.unmappableResult();
}
if (c >= '\uFFFE')
return CoderResult.unmappableForLength(1);
if (dl - dp < 1)
return CoderResult.OVERFLOW;
char e = index2.charAt(index1[(c & mask1) >> shift]
+ (c & mask2));
// If output byte is zero because input char is zero
// then character is mappable, o.w. fail
if (e == '\u0000' && c != '\u0000')
return CoderResult.unmappableForLength(1);
sp++;
da[dp++] = (byte)e;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
/**
* Encode a char array to a byte array using the provided charset. This does
* the same as <code>new String (aCharArray).getBytes (aCharset)</code> just
* without the intermediate objects.
*
* @param aCharset
* Charset to be used. May not be <code>null</code>.
* @param aCharArray
* The char array to be encoded. May not be <code>null</code>.
* @param nOfs
* Offset into char array. Must be ≥ 0.
* @param nLen
* Chars to encode. Must be ≥ 0.
* @return The created byte array. Never <code>null</code>.
* @since 8.6.4
*/
@Nonnull
@ReturnsMutableCopy
public static byte [] encodeCharToBytes (@Nonnull final char [] aCharArray,
@Nonnegative final int nOfs,
@Nonnegative final int nLen,
@Nonnull final Charset aCharset)
{
ValueEnforcer.isArrayOfsLen (aCharArray, nOfs, nLen);
final CharsetEncoder aEncoder = aCharset.newEncoder ();
// We need to perform double, not float, arithmetic; otherwise
// we lose low order bits when nLen is larger than 2^24.
final int nEncodedLen = (int) (nLen * (double) aEncoder.maxBytesPerChar ());
final byte [] aByteArray = new byte [nEncodedLen];
if (nLen == 0)
return aByteArray;
aEncoder.onMalformedInput (CodingErrorAction.REPLACE).onUnmappableCharacter (CodingErrorAction.REPLACE).reset ();
final CharBuffer aSrcBuf = CharBuffer.wrap (aCharArray, nOfs, nLen);
final ByteBuffer aDstBuf = ByteBuffer.wrap (aByteArray);
try
{
CoderResult aRes = aEncoder.encode (aSrcBuf, aDstBuf, true);
if (!aRes.isUnderflow ())
aRes.throwException ();
aRes = aEncoder.flush (aDstBuf);
if (!aRes.isUnderflow ())
aRes.throwException ();
}
catch (final CharacterCodingException x)
{
throw new IllegalStateException (x);
}
final int nDstLen = aDstBuf.position ();
if (nDstLen == aByteArray.length)
return aByteArray;
return Arrays.copyOf (aByteArray, nDstLen);
}
@Override
public void accept(int[] input) {
CharBuffer buffer = Encoder.toCharBuffer(input);
char[] chars = buffer.array();
if (WriteConsoleW(console, chars, chars.length, writtenChars, 0) == 0) {
LOGGER.log(Level.WARNING, "Failed to write out.", WindowsSupport.getLastErrorMessage());
}
}
private CharSequence decode(ByteBuffer buf)
{
// Decode a byte buffer into a CharBuffer
CharBuffer isodcb = null;
CharsetDecoder isodecoder = charset.newDecoder();
try {
isodcb = isodecoder.decode(buf);
} catch (CharacterCodingException e) {
log.error(e);
}
return (CharSequence)isodcb;
}
public static String upTo_(CharBuffer receiver, char c) {
final StringBuilder builder = new StringBuilder();
while (!atEnd(receiver)) {
final Character next = next(receiver);
if (c == next) return builder.toString();
builder.append(next);
}
return builder.toString();
}
protected final CoderResult encodeLoop(CharBuffer src,
ByteBuffer dst)
{
if (src.hasArray() && dst.hasArray())
return encodeArrayLoop(src, dst);
else
return encodeBufferLoop(src, dst);
}
private static String getResponseBodyPreview(byte[] body, Charset charset) {
try {
Reader reader = new InputStreamReader(new ByteArrayInputStream(body), charset);
CharBuffer result = CharBuffer.allocate(MAX_BODY_CHARS_LENGTH);
reader.read(result);
reader.close();
((Buffer) result).flip();
return result.toString() + "... (" + body.length + " bytes)";
} catch (IOException e) {
return e.toString() + ", failed to parse response";
}
}
@Override
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
lastCharBuffer = out;
if (buffer == null) {
if (remainder!=null) {
ByteBuffer tmp = ByteBuffer.allocate(remainder.remaining() + in.remaining());
tmp.put(remainder);
tmp.put(in);
tmp.flip();
CoderResult result = currentDecoder.decode(tmp,out,false);
if (tmp.hasRemaining()) {
remainder = tmp;
}
else {
remainder = null;
}
return result;
}
else {
return currentDecoder.decode(in, out, false);
}
}
if (buffer.remaining() == 0) {
return decodeHead(in, out, false);
} else if (buffer.remaining() < in.remaining()) {
int limit = in.limit();
in.limit(in.position()+buffer.remaining());
buffer.put(in);
in.limit(limit);
return decodeHead(in, out, false);
} else {
buffer.put(in);
return CoderResult.UNDERFLOW;
}
}
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
char[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
assert (sp <= sl);
sp = (sp <= sl ? sp : sl);
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
assert (dp <= dl);
dp = (dp <= dl ? dp : dl);
try {
while (sp < sl) {
char c = sa[sp];
if (dl - dp < 1)
return CoderResult.OVERFLOW;
if (!canEncode(c))
return CoderResult.unmappableForLength(1);
sp++;
if (c >= 0x2761){
da[dp++] = table[c - 0x2761]; // table lookup
} else {
da[dp++] = (byte)(c + 0x20 - 0x2700); // direct map
}
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
@Override
protected CoderResult implFlush (final CharBuffer aCB)
{
if ((m_bBase64mode && m_bStrict) || _areBase64BitsWaiting ())
return CoderResult.malformedForLength (1);
return CoderResult.UNDERFLOW;
}
private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
assert (sp <= sl);
sp = (sp <= sl ? sp : sl);
char[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
assert (dp <= dl);
dp = (dp <= dl ? dp : dl);
try {
while (sp < sl) {
int b = sa[sp];
char c = decode(b);
if (c == '\uFFFD')
return CoderResult.unmappableForLength(1);
if (dl - dp < 1)
return CoderResult.OVERFLOW;
da[dp++] = c;
sp++;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
public String decode(byte[] buffer, int length) {
utf8_decoder.reset();
ByteBuffer bb = ByteBuffer.wrap(buffer, 0, length);
if(charArray.length < length) charArray = new char[length * 2];
CharBuffer cb = CharBuffer.wrap(charArray);
utf8_decoder.decode(bb, cb, true);
utf8_decoder.flush(cb);
return new String(charArray, 0, cb.position());
}
/**
* @param text Text to encode
* @param charset database charset
* @return A buffer with the text encoded
* @usage _advanced_method_
*/
public static ByteBuffer encodeUncompressedText(CharSequence text,
Charset charset)
{
CharBuffer cb = ((text instanceof CharBuffer) ?
(CharBuffer)text : CharBuffer.wrap(text));
return charset.encode(cb);
}
/**
* Checks boundary conditions of CharBuffer based encodes.
*
* @param expected the expected output
* @param input the input to encode
*/
private void checkBoundaryEncodes(String expected, String input) {
final CharBuffer in = CharBuffer.wrap(input.toCharArray());
final int n = expected.length();
final CharBuffer out = CharBuffer.allocate(n);
for (int i=0 ; i<n ; ++i) {
out.clear();
out.position(n - i);
in.clear();
CoderResult cr = _encoder.encode(in, out, true);
out.limit(out.position()).position(n - i);
out.compact();
if (cr.isOverflow()) {
CoderResult cr2 = _encoder.encode(in, out, true);
if (!cr2.isUnderflow()) {
Assert.fail("second encode should finish at offset = "+i);
}
}
out.flip();
String actual = out.toString();
if (!expected.equals(actual)) {
Assert.assertEquals("offset = "+i, expected, actual);
}
}
}
private synchronized void kill() {
resetState();
try {
CharBuffer response = CharBuffer.wrap("{'type': 'dead'}");
outbound.writeTextMessage(response);
} catch (IOException ioe) {
// Ignore
}
}
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
assert (sp <= sl);
sp = (sp <= sl ? sp : sl);
char[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
assert (dp <= dl);
dp = (dp <= dl ? dp : dl);
try {
while (sp < sl) {
if ( sl - sp < 2) {
return CoderResult.UNDERFLOW;
}
int b1 = sa[sp] & 0xFF | 0x80;
int b2 = sa[sp + 1] & 0xFF | 0x80;
char c = decodeDouble(b1, b2);
if (c == UNMAPPABLE_DECODING) {
return CoderResult.unmappableForLength(2);
}
if (dl - dp < 1)
return CoderResult.OVERFLOW;
da[dp++] = c;
sp +=2;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}
protected CoderResult decodeLoop(ByteBuffer src,
CharBuffer dst)
{
if (src.hasArray() && dst.hasArray())
return decodeArrayLoop(src, dst);
else
return decodeBufferLoop(src, dst);
}
protected CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
byte[] sa = src.array();
int sp = src.arrayOffset() + src.position();
int sl = src.arrayOffset() + src.limit();
char[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
try {
while (sp < sl && dp < dl) {
// inline the decodeSingle/Double() for better performance
int inSize = 1;
int b1 = sa[sp] & 0xff;
char c = b2cSB[b1];
if (c == UNMAPPABLE_DECODING) {
if (sl - sp < 2)
return crMalformedOrUnderFlow(b1);
int b2 = sa[sp + 1] & 0xff;
if (b2 < b2Min || b2 > b2Max ||
(c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING) {
return crMalformedOrUnmappable(b1, b2);
}
inSize++;
}
da[dp++] = c;
sp += inSize;
}
return (sp >= sl) ? CoderResult.UNDERFLOW
: CoderResult.OVERFLOW;
} finally {
src.position(sp - src.arrayOffset());
dst.position(dp - dst.arrayOffset());
}
}