socketbuffer.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 655 行 · 第 1/2 页
JAVA
655 行
/*
* $Id: SocketBuffer.java,v 1.1 2003/11/25 11:52:21 epr Exp $
*/
package org.jnode.net;
import org.apache.log4j.Logger;
import org.jnode.driver.Device;
/**
* A SocketBuffer is container of a network packet. It enables efficient
* storage even when various network layers prefix and/or postfix header/footers.
* It also contains other information of a network packet, such as the headers
* of the various network layers.
*
* All numbers larger then a single byte written into this class are
* converted to network byte order.
*
* All numbers larger then a single byte read from this class are
* converted from network byte order.
*
* @author epr
*/
public class SocketBuffer {
private static final int INITIAL_SIZE = 256;
/** My logger */
private final Logger log = Logger.getLogger(getClass());
/** Actual data */
private byte[] data;
/** Size of the buffer that is in use */
private int size;
/** Start offset in data */
private int start;
/** Next buffer, that is concatenated with this one */
private SocketBuffer next;
/** The network device who will be sending, or has received this buffer */
private Device device;
/** Identifying type of the packettype */
private int protocolID;
/** Link layer header (if any) */
private LinkLayerHeader linkLayerHeader;
/** Network layer header (if any) */
private NetworkLayerHeader networkLayerHeader;
/** Transport layer header (if any) */
private TransportLayerHeader transportLayerHeader;
/**
* Create a new instance
*/
public SocketBuffer() {
}
/**
* Create a new instance with a buffer of a given capacity
*/
public SocketBuffer(int initialCapacity) {
this(initialCapacity, 0);
}
/**
* Create a new instance with a buffer of a given capacity
*/
public SocketBuffer(int initialCapacity, int initialStart) {
this.data = new byte[initialCapacity];
}
/**
* Create a clone of the data of src.
* Other attributes are not cloned!.
*
* @param src
*/
public SocketBuffer(SocketBuffer src) {
this.start = 0;
this.size = src.getSize();
this.data = src.toByteArray();
this.next = null;
}
/**
* Create a new instance, using the given byte array as data.
* No copy of the data is made!
* @param data
* @param offset
* @param length
*/
public SocketBuffer(byte[] data, int offset, int length) {
this.data = data;
this.start = offset;
this.size = length;
testBuffer();
}
/**
* Gets the network device who will be sending, or has received this buffer
*/
public Device getDevice() {
return device;
}
/**
* Sets the network device who will be sending, or has received this buffer
* @param device
*/
public void setDevice(Device device) {
this.device = device;
}
/**
* Gets the identifying type of the packettype.
*/
public int getProtocolID() {
return protocolID;
}
/**
* Sets the identifying type of the packettype.
* @param i
*/
public void setProtocolID(int i) {
protocolID = i;
}
/**
* Clear this buffer, so it can be used for another purpose
*
*/
public void clear() {
size = 0;
start = 0;
next = null;
protocolID = 0;
linkLayerHeader = null;
networkLayerHeader = null;
transportLayerHeader = null;
device = null;
// preserve data (if set), we can used it again
}
/**
* Insert a given number of bytes to the front of the buffer.
* The inserted bytes are cleaned with a value of <code>(byte)0</code>.
* @param count
*/
public void insert(int count) {
if (start >= count) {
start -= count;
size += count;
} else {
setSize(size + count);
for (int i = size - 1; i >= count; i--) {
data[start + i] = data[start + i - count];
}
}
for (int i = 0; i < count; i++) {
data[start + i] = 0;
}
testBuffer();
}
/**
* Remove a given number of bytes from the front of the buffer
* @param count
*/
public void pull(int count) {
if (count > size) {
if (next != null) {
// Pull a bit of myself and the rest of next
count -= size;
start = size;
size = 0;
next.pull(count);
} else {
throw new IllegalArgumentException("Cannot pull " + count + " bytes (" + start + "," + size + ")");
}
} else {
start += count;
size -= count;
}
testBuffer();
}
/**
* Undo a pull action.
* This method is different from insert, as this method can only unpull
* that what has been removed by an earlier call to pull, insert will
* actually make new room at the head on the buffer.
* @param count
* @throws IllegalArgumentException It is not possible to unpull count bytes.
*/
public void unpull(int count) {
if (start >= count) {
start -= count;
size += count;
} else {
if (next != null) {
// Unpull most of next and that what I can from me
final int remaining = (count - start);
size += start;
start = 0;
next.unpull(remaining);
} else {
throw new IllegalArgumentException("Cannot unpull " + count + " bytes (" + start + "," + size + ")");
}
}
testBuffer();
}
/**
* Remove data from the tail of the buffer, until size <= length.
* If the current size < length, nothing happens.
* @param length
*/
public void trim(int length) {
if (length < size) {
// Cut the tail of myself and remove any next buffer
size = length;
next = null;
} else if (length == size) {
// Remove any next buffer
next = null;
} else {
// Length > size
if (next != null) {
next.trim(length - size);
}
}
}
/**
* Insert a given number of bytes to the back of the buffer
* @param count
*/
public void append(int count) {
if (next != null) {
next.append(count);
} else {
setSize(size + count);
}
testBuffer();
}
/**
* Insert a given number of bytes to the front of the buffer
* @param src
* @param srcOffset
* @param length
*/
public void append(byte[] src, int srcOffset, int length) {
if (next != null) {
next.append(src, srcOffset, length);
} else {
final int dstOffset = start + size;
setSize(size + length);
System.arraycopy(src, srcOffset, data, dstOffset, length);
}
testBuffer();
}
/**
* Append a complete buffer to the end of this buffer.
* @param skbuf
*/
public void append(SocketBuffer skbuf) {
if (next != null) {
next.append(skbuf);
} else {
next = skbuf;
}
testBuffer();
}
/**
* Append a buffer to the end of this buffer starting at the given offset
* in the appended buffer.
* @param skbufOffset
* @param skbuf
*/
public void append(int skbufOffset, SocketBuffer skbuf) {
final byte[] src = skbuf.toByteArray();
append(src, skbufOffset, src.length - skbufOffset);
}
/**
* Append a buffer to the end of this buffer with only a given amount
* of bytes.
* The given buffer must not contain a next buffer and must have a size
* greater or equal to length
* @param skbuf
*/
public void append(SocketBuffer skbuf, int length) throws IllegalArgumentException {
if (length == 0) {
return;
}
if (next != null) {
next.append(skbuf, length);
} else {
if (length < 0) {
throw new IllegalArgumentException("Length < 0");
}
if (skbuf.next != null) {
throw new IllegalArgumentException("skbuf.next != null");
}
if (skbuf.size < length) {
throw new IllegalArgumentException("skbuf.size < length");
}
next = skbuf;
skbuf.size = length;
}
testBuffer();
}
/**
* Gets a byte in the buffer
* @param index
*/
public int get(int index) {
if (index >= size) {
if (next != null) {
return next.get(index - size);
} else {
throw new IndexOutOfBoundsException("at index " + index);
}
} else {
return data[start + index] & 0xFF;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?