📄 bytebuffer.java
字号:
//////////////////////////////// // String getters and putters // //////////////////////////////// /** * Reads a <code>NUL</code>-terminated string from this buffer using the * specified <code>decoder</code> and returns it. This method reads * until the limit of this buffer if no <tt>NUL</tt> is found. */ public String getString(CharsetDecoder decoder) throws CharacterCodingException { if (!hasRemaining()) { return ""; } boolean utf16 = decoder.charset().name().startsWith("UTF-16"); int oldPos = position(); int oldLimit = limit(); int end; if (!utf16) { while (hasRemaining()) { if (get() == 0) { break; } } end = position(); if (end == oldLimit && get(end - 1) != 0) { limit(end); } else { limit(end - 1); } } else { while (remaining() >= 2) { boolean highZero = (get() == 0); boolean lowZero = (get() == 0); if (highZero && lowZero) { break; } } end = position(); if (end == oldLimit || end == oldLimit - 1) { limit(end); } else { limit(end - 2); } } position(oldPos); if (!hasRemaining()) { limit(oldLimit); position(end); return ""; } decoder.reset(); int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1; CharBuffer out = CharBuffer.allocate(expectedLength); for (;;) { CoderResult cr; if (hasRemaining()) { cr = decoder.decode(buf(), out, true); } else { cr = decoder.flush(out); } if (cr.isUnderflow()) { break; } if (cr.isOverflow()) { CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength); out.flip(); o.put(out); out = o; continue; } if (cr.isError()) { // Revert the buffer back to the previous state. limit(oldLimit); position(oldPos); cr.throwException(); } } limit(oldLimit); position(end); return out.flip().toString(); } /** * Reads a <code>NUL</code>-terminated string from this buffer using the * specified <code>decoder</code> and returns it. * * @param fieldSize the maximum number of bytes to read */ public String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException { checkFieldSize(fieldSize); if (fieldSize == 0) { return ""; } if (!hasRemaining()) { return ""; } boolean utf16 = decoder.charset().name().startsWith("UTF-16"); if (utf16 && ((fieldSize & 1) != 0)) { throw new IllegalArgumentException("fieldSize is not even."); } int oldPos = position(); int oldLimit = limit(); int end = position() + fieldSize; if (oldLimit < end) { throw new BufferUnderflowException(); } int i; if (!utf16) { for (i = 0; i < fieldSize; i++) { if (get() == 0) { break; } } if (i == fieldSize) { limit(end); } else { limit(position() - 1); } } else { for (i = 0; i < fieldSize; i += 2) { boolean highZero = (get() == 0); boolean lowZero = (get() == 0); if (highZero && lowZero) { break; } } if (i == fieldSize) { limit(end); } else { limit(position() - 2); } } position(oldPos); if (!hasRemaining()) { limit(oldLimit); position(end); return ""; } decoder.reset(); int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1; CharBuffer out = CharBuffer.allocate(expectedLength); for (;;) { CoderResult cr; if (hasRemaining()) { cr = decoder.decode(buf(), out, true); } else { cr = decoder.flush(out); } if (cr.isUnderflow()) { break; } if (cr.isOverflow()) { CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength); out.flip(); o.put(out); out = o; continue; } if (cr.isError()) { // Revert the buffer back to the previous state. limit(oldLimit); position(oldPos); cr.throwException(); } } limit(oldLimit); position(end); return out.flip().toString(); } /** * Writes the content of <code>in</code> into this buffer using the * specified <code>encoder</code>. This method doesn't terminate * string with <tt>NUL</tt>. You have to do it by yourself. * * @throws BufferOverflowException if the specified string doesn't fit */ public ByteBuffer putString(CharSequence val, CharsetEncoder encoder) throws CharacterCodingException { if (val.length() == 0) { return this; } CharBuffer in = CharBuffer.wrap(val); encoder.reset(); int expandedState = 0; for (;;) { CoderResult cr; if (in.hasRemaining()) { cr = encoder.encode(in, buf(), true); } else { cr = encoder.flush(buf()); } if (cr.isUnderflow()) { break; } if (cr.isOverflow()) { if (isAutoExpand()) { switch (expandedState) { case 0: autoExpand((int) Math.ceil(in.remaining() * encoder.averageBytesPerChar())); expandedState++; break; case 1: autoExpand((int) Math.ceil(in.remaining() * encoder.maxBytesPerChar())); expandedState++; break; default: throw new RuntimeException("Expanded by " + (int) Math.ceil(in.remaining() * encoder.maxBytesPerChar()) + " but that wasn't enough for '" + val + "'"); } continue; } } else { expandedState = 0; } cr.throwException(); } return this; } /** * Writes the content of <code>in</code> into this buffer as a * <code>NUL</code>-terminated string using the specified * <code>encoder</code>. * <p> * If the charset name of the encoder is UTF-16, you cannot specify * odd <code>fieldSize</code>, and this method will append two * <code>NUL</code>s as a terminator. * <p> * Please note that this method doesn't terminate with <code>NUL</code> * if the input string is longer than <tt>fieldSize</tt>. * * @param fieldSize the maximum number of bytes to write */ public ByteBuffer putString(CharSequence val, int fieldSize, CharsetEncoder encoder) throws CharacterCodingException { checkFieldSize(fieldSize); if (fieldSize == 0) return this; autoExpand(fieldSize); boolean utf16 = encoder.charset().name().startsWith("UTF-16"); if (utf16 && ((fieldSize & 1) != 0)) { throw new IllegalArgumentException("fieldSize is not even."); } int oldLimit = limit(); int end = position() + fieldSize; if (oldLimit < end) { throw new BufferOverflowException(); } if (val.length() == 0) { if (!utf16) { put((byte) 0x00); } else { put((byte) 0x00); put((byte) 0x00); } position(end); return this; } CharBuffer in = CharBuffer.wrap(val); limit(end); encoder.reset(); for (;;) { CoderResult cr; if (in.hasRemaining()) { cr = encoder.encode(in, buf(), true); } else { cr = encoder.flush(buf()); } if (cr.isUnderflow() || cr.isOverflow()) { break; } cr.throwException(); } limit(oldLimit); if (position() < end) { if (!utf16) { put((byte) 0x00); } else { put((byte) 0x00); put((byte) 0x00); } } position(end); return this; } /** * Reads a string which has a 16-bit length field before the actual * encoded string, using the specified <code>decoder</code> and returns it. * This method is a shortcut for <tt>getPrefixedString(2, decoder)</tt>. */ public String getPrefixedString(CharsetDecoder decoder) throws CharacterCodingException { return getPrefixedString(2, decoder); } /** * Reads a string which has a length field before the actual * encoded string, using the specified <code>decoder</code> and returns it. * * @param prefixLength the length of the length field (1, 2, or 4) */ public String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException { if (!prefixedDataAvailable(prefixLength)) { throw new BufferUnderflowException(); } int fieldSize = 0; switch (prefixLength) { case 1: fieldSize = getUnsigned(); break; case 2: fieldSize = getUnsignedShort(); break; case 4: fieldSize = getInt(); break; } if (fieldSize == 0) { return ""; } boolean utf16 = decoder.charset().name().startsWith("UTF-16"); if (utf16 && ((fieldSize & 1) != 0)) { throw new BufferDataException( "fieldSize is not even for a UTF-16 string."); } int oldLimit = limit(); int end = position() + fieldSize; if (oldLimit < end) { throw new BufferUnderflowException(); } limit(end); decoder.reset(); int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1; CharBuffer out = CharBuffer.allocate(expectedLength); for (;;) { CoderResult cr; if (hasRemaining()) { cr = decoder.decode(buf(), out, true); } else { cr = decoder.flush(out); } if (cr.isUnderflow()) { break; } if (cr.isOverflow()) { CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength); out.flip(); o.put(out); out = o; continue; } cr.throwException(); } limit(oldLimit); position(end); return out.flip().toString(); } /** * Writes the content of <code>in</code> into this buffer as a * string which has a 16-bit length field before the actual * encoded string, using the specified <code>encoder</code>.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -