⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bytebuffer.java

📁 apache 的一个socket框架
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
     * This method is a shortcut for <tt>putPrefixedString(in, 2, 0, encoder)</tt>.     *     * @throws BufferOverflowException if the specified string doesn't fit     */    public ByteBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder)            throws CharacterCodingException {        return putPrefixedString(in, 2, 0, encoder);    }    /**     * 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>.     * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, 0, encoder)</tt>.     *     * @param prefixLength the length of the length field (1, 2, or 4)     *     * @throws BufferOverflowException if the specified string doesn't fit     */    public ByteBuffer putPrefixedString(CharSequence in, int prefixLength,            CharsetEncoder encoder) throws CharacterCodingException {        return putPrefixedString(in, prefixLength, 0, encoder);    }    /**     * 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>.     * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)</tt>.     *     * @param prefixLength the length of the length field (1, 2, or 4)     * @param padding      the number of padded <tt>NUL</tt>s (1 (or 0), 2, or 4)     *     * @throws BufferOverflowException if the specified string doesn't fit     */    public ByteBuffer putPrefixedString(CharSequence in, int prefixLength,            int padding, CharsetEncoder encoder)            throws CharacterCodingException {        return putPrefixedString(in, prefixLength, padding, (byte) 0, encoder);    }    /**     * 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>.     *     * @param prefixLength the length of the length field (1, 2, or 4)     * @param padding      the number of padded bytes (1 (or 0), 2, or 4)     * @param padValue     the value of padded bytes     *     * @throws BufferOverflowException if the specified string doesn't fit     */    public ByteBuffer 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);        int expectedLength = (int) (in.remaining() * encoder                .averageBytesPerChar()) + 1;        skip(prefixLength); // make a room for the length field        int oldPos = position();        encoder.reset();        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() && isAutoExpand()) {                autoExpand(expectedLength);                continue;            }            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;    }    /**     * Reads a Java object from the buffer using the context {@link ClassLoader}     * of the current thread.     */    public Object getObject() throws ClassNotFoundException {        return getObject(Thread.currentThread().getContextClassLoader());    }    /**     * Reads a Java object from the buffer using the specified <tt>classLoader</tt>.     */    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()) {                protected ObjectStreamClass readClassDescriptor()                        throws IOException, ClassNotFoundException {                    String className = readUTF();                    Class<?> clazz = Class                            .forName(className, true, classLoader);                    return ObjectStreamClass.lookup(clazz);                }            };            return in.readObject();        } catch (IOException e) {            throw new BufferDataException(e);        } finally {            limit(oldLimit);        }    }    /**     * Writes the specified Java object to the buffer.     */    public ByteBuffer putObject(Object o) {        int oldPos = position();        skip(4); // Make a room for the length field.        try {            ObjectOutputStream out = new ObjectOutputStream(asOutputStream()) {                protected void writeClassDescriptor(ObjectStreamClass desc)                        throws IOException {                    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;    }    /**     * Returns <tt>true</tt> if this buffer contains a data which has a data     * length as a prefix and the buffer has remaining data as enough as     * specified in the data length field.  This method is identical with     * <tt>prefixedDataAvailable( prefixLength, Integer.MAX_VALUE )</tt>.     * Please not that using this method can allow DoS (Denial of Service)     * attack in case the remote peer sends too big data length value.     * It is recommended to use {@link #prefixedDataAvailable(int, int)}     * instead.     *     * @param prefixLength the length of the prefix field (1, 2, or 4)     *     * @throws IllegalArgumentException if prefixLength is wrong     * @throws BufferDataException      if data length is negative     */    public boolean prefixedDataAvailable(int prefixLength) {        return prefixedDataAvailable(prefixLength, Integer.MAX_VALUE);    }    /**     * Returns <tt>true</tt> if this buffer contains a data which has a data     * length as a prefix and the buffer has remaining data as enough as     * specified in the data length field.     *     * @param prefixLength  the length of the prefix field (1, 2, or 4)     * @param maxDataLength the allowed maximum of the read data length     *     * @throws IllegalArgumentException if prefixLength is wrong     * @throws BufferDataException      if data length is negative or greater then <tt>maxDataLength</tt>     */    public boolean prefixedDataAvailable(int prefixLength, int maxDataLength) {        if (remaining() < prefixLength) {            return false;        }        int dataLength;        switch (prefixLength) {        case 1:            dataLength = getUnsigned(position());            break;        case 2:            dataLength = getUnsignedShort(position());            break;        case 4:            dataLength = getInt(position());            break;        default:            throw new IllegalArgumentException("prefixLength: " + prefixLength);        }        if (dataLength < 0 || dataLength > maxDataLength) {            throw new BufferDataException("dataLength: " + dataLength);        }        return remaining() - prefixLength >= dataLength;    }    //////////////////////////    // Skip or fill methods //    //////////////////////////    /**     * Forwards the position of this buffer as the specified <code>size</code>     * bytes.     */    public ByteBuffer skip(int size) {        autoExpand(size);        return position(position() + size);    }    /**     * Fills this buffer with the specified value.     * This method moves buffer position forward.     */    public ByteBuffer fill(byte value, int size) {        autoExpand(size);        int q = size >>> 3;        int r = size & 7;        if (q > 0) {            int intValue = value | (value << 8) | (value << 16) | (value << 24);            long longValue = intValue;            longValue <<= 32;            longValue |= intValue;            for (int i = q; i > 0; i--) {                putLong(longValue);            }        }        q = r >>> 2;        r = r & 3;        if (q > 0) {            int intValue = value | (value << 8) | (value << 16) | (value << 24);            putInt(intValue);        }        q = r >> 1;        r = r & 1;        if (q > 0) {            short shortValue = (short) (value | (value << 8));            putShort(shortValue);        }        if (r > 0) {            put(value);        }        return this;    }    /**     * Fills this buffer with the specified value.     * This method does not change buffer position.     */    public ByteBuffer fillAndReset(byte value, int size) {        autoExpand(size);        int pos = position();        try {            fill(value, size);        } finally {            position(pos);        }        return this;    }    /**     * Fills this buffer with <code>NUL (0x00)</code>.     * This method moves buffer position forward.     */    public ByteBuffer fill(int size) {        autoExpand(size);        int q = size >>> 3;        int r = size & 7;        for (int i = q; i > 0; i--) {            putLong(0L);        }        q = r >>> 2;        r = r & 3;        if (q > 0) {            putInt(0);        }        q = r >> 1;        r = r & 1;        if (q > 0) {            putShort((short) 0);        }        if (r > 0) {            put((byte) 0);        }        return this;    }    /**     * Fills this buffer with <code>NUL (0x00)</code>.     * This method does not change buffer position.     */    public ByteBuffer fillAndReset(int size) {        autoExpand(size);        int pos = position();        try {            fill(size);        } finally {            position(pos);        }        return this;    }    /**     * This method forwards the call to {@link #expand(int)} only when     * <tt>autoExpand</tt> property is <tt>true</tt>.     */    protected ByteBuffer autoExpand(int expectedRemaining) {        if (isAutoExpand()) {            expand(expectedRemaining);        }        return this;    }    /**     * This method forwards the call to {@link #expand(int)} only when     * <tt>autoExpand</tt> property is <tt>true</tt>.     */    protected ByteBuffer autoExpand(int pos, int expectedRemaining) {        if (isAutoExpand()) {            expand(pos, expectedRemaining);        }        return this;    }    private static void checkFieldSize(int fieldSize) {        if (fieldSize < 0) {            throw new IllegalArgumentException("fieldSize cannot be negative: "                    + fieldSize);        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -