hprose.io.ByteBufferStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hprose-java Show documentation
Show all versions of hprose-java Show documentation
Hprose is a High Performance Remote Object Service Engine.
It is a modern, lightweight, cross-language, cross-platform, object-oriented, high performance, remote dynamic communication middleware. It is not only easy to use, but powerful. You just need a little time to learn, then you can use it to easily construct cross language cross platform distributed application system.
Hprose supports many programming languages, for example:
* AAuto Quicker
* ActionScript
* ASP
* C++
* Dart
* Delphi/Free Pascal
* dotNET(C#, Visual Basic...)
* Golang
* Java
* JavaScript
* Node.js
* Objective-C
* Perl
* PHP
* Python
* Ruby
* ...
Through Hprose, You can conveniently and efficiently intercommunicate between those programming languages.
This project is the implementation of Hprose for Java.
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* ByteBufferStream.java *
* *
* ByteBuffer Stream for Java. *
* *
* LastModified: Jul 15, 2015 *
* Author: Ma Bingyao *
* *
\**********************************************************/
package hprose.io;
import hprose.common.HproseException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
public final class ByteBufferStream {
final static class ByteBufferPool {
private final int POOLNUM = 12;
private final int POOLSIZE = 32;
private final ByteBuffer[][] pool = new ByteBuffer[POOLNUM][];
private final int[] position = new int[POOLNUM];
private final static int[] debruijn = new int[] {
0, 1, 28, 2, 29, 14, 24, 3,
30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7,
26, 12, 18, 6, 11, 5, 10, 9
};
private static int log2(int x) {
return debruijn[(x & -x) * 0x077CB531 >>> 27];
}
private ByteBufferPool() {
for (int i = 0; i < POOLNUM; ++i) {
pool[i] = new ByteBuffer[POOLSIZE];
position[i] = -1;
}
}
private ByteBuffer allocate(int capacity) {
capacity = pow2roundup(capacity);
if (capacity < 1024) {
return ByteBuffer.allocate(capacity);
}
int index = log2(capacity) - 10;
if (index < POOLNUM && position[index] >= 0) {
int pos = position[index];
ByteBuffer byteBuffer = pool[index][pos];
pool[index][pos] = null;
position[index] = pos - 1;
if (byteBuffer != null) return byteBuffer;
}
return ByteBuffer.allocateDirect(capacity);
}
private void free(ByteBuffer buffer) {
if (buffer.isDirect()) {
int capacity = buffer.capacity();
if (capacity == pow2roundup(capacity)) {
buffer.clear();
int index = log2(capacity) - 10;
if (index >= 0 && index < POOLNUM) {
int pos = position[index];
if (pos < POOLSIZE - 1) {
pool[index][++pos] = buffer;
position[index] = pos;
}
}
}
}
}
}
private final static ThreadLocal byteBufferPool = new ThreadLocal() {
@Override
protected ByteBufferPool initialValue() {
return new ByteBufferPool();
}
};
public ByteBuffer buffer;
InputStream istream;
OutputStream ostream;
private static int pow2roundup(int x) {
--x;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x + 1;
}
public final static ByteBuffer allocate(int capacity) {
return byteBufferPool.get().allocate(capacity);
}
public final static void free(ByteBuffer buffer) {
byteBufferPool.get().free(buffer);
}
public ByteBufferStream() {
this(1024);
}
public ByteBufferStream(int capacity) {
buffer = allocate(capacity);
}
public ByteBufferStream(ByteBuffer buffer) {
this.buffer = buffer;
}
public final static ByteBufferStream wrap(byte[] array, int offset, int length) {
return new ByteBufferStream(ByteBuffer.wrap(array, offset, length));
}
public final static ByteBufferStream wrap(byte[] array) {
return new ByteBufferStream(ByteBuffer.wrap(array));
}
public final void close() {
if (buffer != null) {
free(buffer);
buffer = null;
}
}
public final InputStream getInputStream() {
if (istream == null) {
istream = new ByteBufferInputStream(this);
}
return istream;
}
public final OutputStream getOutputStream() {
if (ostream == null) {
ostream = new ByteBufferOutputStream(this);
}
return ostream;
}
public final int read() {
if (buffer.hasRemaining()) {
return buffer.get() & 0xff;
}
else {
return -1;
}
}
public final int read(byte b[]) {
return read(b, 0, b.length);
}
public final int read(byte b[], int off, int len) {
if (len <= 0) {
return 0;
}
int remain = buffer.remaining();
if (remain <= 0) {
return -1;
}
if (len >= remain) {
buffer.get(b, off, remain);
return remain;
}
buffer.get(b, off, len);
return len;
}
public final int read(ByteBuffer b) {
int len = b.remaining();
if (len <= 0) {
return 0;
}
int remain = buffer.remaining();
if (remain <= 0) {
return -1;
}
if (len >= remain) {
b.put(buffer);
return remain;
}
int oldlimit = buffer.limit();
buffer.limit(buffer.position() + len);
b.put(buffer);
buffer.limit(oldlimit);
return len;
}
public final long skip(long n) {
if (n <= 0) {
return 0;
}
int remain = buffer.remaining();
if (remain <= 0) {
return 0;
}
if (n > remain) {
buffer.position(buffer.limit());
return remain;
}
buffer.position(buffer.position() + (int) n);
return n;
}
public final int available() {
return buffer.remaining();
}
public final boolean markSupported() {
return true;
}
public final void mark(int readlimit) {
buffer.mark();
}
public final void reset() {
buffer.reset();
}
private void grow(int n) {
if (buffer.remaining() < n) {
int required = buffer.position() + n;
if (required > buffer.capacity()) {
int size = pow2roundup(required);
ByteBuffer buf = allocate(size);
buffer.flip();
buf.put(buffer);
free(buffer);
buffer = buf;
}
else {
buffer.limit(required);
}
}
}
public final void write(int b) {
grow(1);
buffer.put((byte) b);
}
public final void write(byte b[]) {
write(b, 0, b.length);
}
public final void write(byte b[], int off, int len) {
grow(len);
buffer.put(b, off, len);
}
public final void write(ByteBuffer b) {
grow(b.remaining());
buffer.put(b);
}
public final void flip() {
if (buffer.position() != 0) {
buffer.flip();
}
}
public final void rewind() {
buffer.rewind();
}
public final byte[] toArray() {
flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
return data;
}
public final void readFrom(InputStream istream) throws IOException {
byte[] b = new byte[8192];
for (;;) {
int n = istream.read(b);
if (n == -1) {
break;
}
write(b, 0, n);
}
}
public final void writeTo(OutputStream ostream) throws IOException {
if (buffer.hasArray()) {
ostream.write(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
}
else {
byte[] b = new byte[8192];
for (;;) {
int n = read(b);
if (n == -1) {
break;
}
ostream.write(b, 0, n);
}
}
}
public final void readFrom(ByteChannel channel, int length) throws IOException {
int n = 0;
grow(length);
buffer.limit(buffer.position() + length);
while (n < length) {
int nn = channel.read(buffer);
if (nn == -1) {
break;
}
n += nn;
}
if (n < length) {
throw new HproseException("Unexpected EOF");
}
}
public final void writeTo(ByteChannel channel) throws IOException {
while (buffer.hasRemaining()) {
channel.write(buffer);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy