📄 abstractiobuffer.java
字号:
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(); } /** * {@inheritDoc} */ @Override public IoBuffer 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; } /** * {@inheritDoc} */ @Override public IoBuffer 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; } /** * {@inheritDoc} */ @Override 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) * @param decoder the decoder to use for decoding the string * @return the prefixed string * @throws CharacterCodingException when decoding fails * @throws BufferUnderflowException when there is not enough data available */ @Override 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(); } /** * {@inheritDoc} */ @Override public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException { return putPrefixedString(in, 2, 0, encoder); } /** * {@inheritDoc} */ @Override public IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder) throws CharacterCodingException { return putPrefixedString(in, prefixLength, 0, encoder); } /** * {@inheritDoc} */ @Override public IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder) throws CharacterCodingException { return putPrefixedString(in, prefixLength, padding, (byte) 0, encoder); } /** * {@inheritDoc} */ @Override public IoBuffer putPrefixedString(CharSequence val, int prefixLength, int padding, byte padValue, CharsetEncoder encoder) throws CharacterCodingException { int maxLength; switch (prefixLength) { case 1: maxLength = 255; break; case 2: maxLength = 65535; break; case 4: maxLength = Integer.MAX_VALUE; break; default: throw new IllegalArgumentException("prefixLength: " + prefixLength); } if (val.length() > maxLength) { throw new IllegalArgumentException( "The specified string is too long."); } if (val.length() == 0) { switch (prefixLength) { case 1: put((byte) 0); break; case 2: putShort((short) 0); break; case 4: putInt(0); break; } return this; } int padMask; switch (padding) { case 0: case 1: padMask = 0; break; case 2: padMask = 1; break; case 4: padMask = 3; break; default: throw new IllegalArgumentException("padding: " + padding); } CharBuffer in = CharBuffer.wrap(val); skip(prefixLength); // make a room for the length field int oldPos = position(); encoder.reset(); int expandedState = 0; for (;;) { CoderResult cr; if (in.hasRemaining()) { cr = encoder.encode(in, buf(), true); } else { cr = encoder.flush(buf()); } if (position() - oldPos > maxLength) { throw new IllegalArgumentException( "The specified string is too long."); } 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(); } // Write the length field fill(padValue, padding - (position() - oldPos & padMask)); int length = position() - oldPos; switch (prefixLength) { case 1: put(oldPos - 1, (byte) length); break; case 2: putShort(oldPos - 2, (short) length); break; case 4: putInt(oldPos - 4, length); break; } return this; } /** * {@inheritDoc} */ @Override public Object getObject() throws ClassNotFoundException { return getObject(Thread.currentThread().getContextClassLoader()); } /** * {@inheritDoc} */ @Override public Object getObject(final ClassLoader classLoader) throws ClassNotFoundException { if (!prefixedDataAvailable(4)) { throw new BufferUnderflowException(); } int length = getInt(); if (length <= 4) { throw new BufferDataException( "Object length should be greater than 4: " + length); } int oldLimit = limit(); limit(position() + length); try { ObjectInputStream in = new ObjectInputStream(asInputStream()) { @Override protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { int type = read(); if (type < 0) { throw new EOFException(); } switch (type) { case 0: // Primitive types return super.readClassDescriptor(); case 1: // Non-primitive types String className = readUTF(); Class<?> clazz = Class.forName(className, true, classLoader); return ObjectStreamClass.lookup(clazz); default: throw new StreamCorruptedException( "Unexpected class descriptor type: " + type); } } @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { String name = desc.getName(); try { return Class.forName(name, false, classLoader); } catch (ClassNotFoundException ex) { return super.resolveClass(desc); } } }; return in.readObject(); } catch (IOException e) { throw new BufferDataException(e); } finally { limit(oldLimit); } } /** * {@inheritDoc} */ @Override public IoBuffer putObject(Object o) { int oldPos = position(); skip(4); // Make a room for the length field. try { ObjectOutputStream out = new ObjectOutputStream(asOutputStream()) { @Override protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { if (desc.forClass().isPrimitive()) { write(0); super.writeClassDescriptor(desc); } else { write(1); writeUTF(desc.getName()); } } }; out.writeObject(o); out.flush(); } catch (IOException e) { throw new BufferDataException(e); } // Fill the length field int newPos = position(); position(oldPos); putInt(newPos - oldPos - 4); position(newPos); return this; } /** * {@inheritDoc} */ @Override public boolean prefixedDataAvailable(int prefixLength) { return prefixedDataAvailable(prefixLength, Integer.MAX_VALUE); } /** * {@inheritDoc} */ @Override public boolean prefixedDataAvailable(int prefixLength, int maxDataLength) { if (remaining() < prefixLength) { return false; } int dataLength; switch (prefixLength) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -