/*
* Copyright 2009 Red Hat, Inc.
*
* Red Hat licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.jboss.netty.buffer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.util.NoSuchElementException;
import android.util.Log;
/**
* A skeletal implementation of a buffer.
*
*/
/**
* [超超超重要]
* ChannelBufferの実装クラス
*
* @author Owner
*
*/
public abstract class AbstractChannelBuffer implements ChannelBuffer {
public int readerIndex;
public int writerIndex;
public int markedReaderIndex;
public int markedWriterIndex;
public int readerIndex() {
return readerIndex;
}
public void readerIndex(int readerIndex) {
this.readerIndex = readerIndex;
}
public int writerIndex() {
return writerIndex;
}
public void writerIndex(int writerIndex) {
this.writerIndex = writerIndex;
}
public void setIndex(int readerIndex, int writerIndex) {
this.readerIndex = readerIndex;
this.writerIndex = writerIndex;
}
public void clear() {
readerIndex = writerIndex = 0;
}
public int readableBytes() {
return writerIndex - readerIndex;
}
public int writableBytes() {
return capacity() - writerIndex;
}
public void markReaderIndex() {
markedReaderIndex = readerIndex;
}
public void resetReaderIndex() {
readerIndex(markedReaderIndex);
}
public void markWriterIndex() {
markedWriterIndex = writerIndex;
}
public void resetWriterIndex() {
writerIndex = markedWriterIndex;
}
//discard=捨てる
public void discardReadBytes() {
if (readerIndex == 0) {
return;
}
setBytes(0, this, readerIndex, writerIndex - readerIndex);
writerIndex -= readerIndex;
markedReaderIndex = Math.max(markedReaderIndex - readerIndex, 0);
markedWriterIndex = Math.max(markedWriterIndex - readerIndex, 0);
readerIndex = 0;
}
public int getMedium(int index) {
int value = 0;
try{//検証
value = getUnsignedMedium(index);
}catch(Exception e){
e.printStackTrace();
return 0;
}
if ((value & 0x800000) != 0) {
value |= 0xff000000;
}
return value;
}
public long getUnsignedInt(int index) {
try{//検証
return getInt(index) & 0xFFFFFFFFL;
}catch(Exception e){
e.printStackTrace();
return 0xFFFFFFFFL;
}
}
public char getChar(int index) {
try{//検証
return (char) getShort(index);
}catch(Exception e){
e.printStackTrace();
return (char)0xFF;
}
}
public float getFloat(int index) {
try{//検証
return Float.intBitsToFloat(getInt(index));
}catch(Exception e){
e.printStackTrace();
return Float.intBitsToFloat(0xFFFFFFFF);
}
}
public double getDouble(int index) {
try{//検証
return Double.longBitsToDouble(getLong(index));
}catch(Exception e){
e.printStackTrace();
return Double.longBitsToDouble(0xFFFFFFFFL);
}
}
public void setChar(int index, int value) {
try{//検証
setShort(index, value);
}catch(Exception e){
e.printStackTrace();
}
}
public void setFloat(int index, float value) {
try{//検証
setInt(index, Float.floatToRawIntBits(value));
}catch(Exception e){
e.printStackTrace();
}
}
public void setDouble(int index, double value) {
try{//検証
setLong(index, Double.doubleToRawLongBits(value));
}catch(Exception e){
e.printStackTrace();
}
}
// public void setZero(int index, int length) {
// if (length == 0) {
// return;
// }
// if (length < 0) {
// throw new IllegalArgumentException(
// "length must be 0 or greater than 0.");
// }
//
// int nLong = length >>> 3;
// int nBytes = length & 7;
// for (int i = nLong; i > 0; i --) {
// setLong(index, 0);
// index += 8;
// }
// if (nBytes == 4) {
// setInt(index, 0);
// } else if (nBytes < 4) {
// for (int i = nBytes; i > 0; i --) {
// setByte(index, (byte) 0);
// index ++;
// }
// } else {
// setInt(index, 0);
// index += 4;
// for (int i = nBytes - 4; i > 0; i --) {
// setByte(index, (byte) 0);
// index ++;
// }
// }
// }
public byte readByte() {
return getByte(readerIndex++);
}
public short readShort() {
// Log.d("readShort","");
short v = getShort(readerIndex);
readerIndex += 2;
return v;
}
public int readMedium() {
int value = readUnsignedMedium();
if ((value & 0x800000) != 0) {
value |= 0xff000000;
}
return value;
}
public int readUnsignedMedium() {
// Log.d("readUnsignedMedium","");
int v = getUnsignedMedium(readerIndex);
readerIndex += 3;
return v;
}
public int readInt() {
// Log.d("readInt","");
int v = getInt(readerIndex);
readerIndex += 4;
return v;
}
public long readLong() {
// Log.d("readLong","");
long v = 0L;
try{//検証
v = getLong(readerIndex);//現在位置から8バイト取得
}catch(Exception e){
readerIndex = writerIndex;
return 0xFFFFFFFFL;
}
readerIndex += 8;//8バイト進める
return v;
}
public char readChar() {
return (char) readShort();
}
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
public double readDouble() {
return Double.longBitsToDouble(readLong());
}
public ChannelBuffer readBytes(int length) {
// Log.d("ChannelBuffer","length");
if (length == 0) {
return ChannelBuffers.EMPTY_BUFFER;
}
ChannelBuffer buf = ChannelBuffers.buffer(order(), length);
buf.writeBytes(this, readerIndex, length);
readerIndex += length;
return buf;
}
@Deprecated
public ChannelBuffer readBytes(ChannelBufferIndexFinder endIndexFinder) {
int endIndex = indexOf(readerIndex, writerIndex, endIndexFinder);
if (endIndex < 0) {
throw new NoSuchElementException();
}
return readBytes(endIndex - readerIndex);
}
public ChannelBuffer readSlice(int length) {
ChannelBuffer slice = slice(readerIndex, length);
readerIndex += length;
return slice;
}
@Deprecated
public ChannelBuffer readSlice(ChannelBufferIndexFinder endIndexFinder) {
int endIndex = indexOf(readerIndex, writerIndex, endIndexFinder);
if (endIndex < 0) {
throw new NoSuchElementException();
}
return readSlice(endIndex - readerIndex);
}
public void readBytes(byte[] dst, int dstIndex, int length) {
// Log.d("readBytes","dst dstIndex length");
getBytes(readerIndex, dst, dstIndex, length);
readerIndex += length;
}
public void readBytes(ChannelBuffer dst, int length) {
// if (length > dst.writableBytes()) {
// throw new IndexOutOfBoundsException();
// }
readBytes(dst, dst.writerIndex(), length);
dst.writerIndex(dst.writerIndex() + length);
}
public void readBytes(ChannelBuffer dst, int dstIndex, int length) {
// Log.d("readBytes","dst dstIndex length");
getBytes(readerIndex, dst, dstIndex, length);
readerIndex += length;
}
public void readBytes(ByteBuffer dst) {
int length = dst.remaining();
getBytes(readerIndex, dst);
readerIndex += length;
}
public int readBytes(GatheringByteChannel out, int length)
throws IOException {
int readBytes = getBytes(readerIndex, out, length);
readerIndex += readBytes;
return readBytes;
}
public void readBytes(OutputStream out, int length) throws IOException {
getBytes(readerIndex, out, length);
readerIndex += length;
}
public void skipBytes(int length) {
int newReaderIndex = readerIndex + length;
readerIndex = newReaderIndex;
}
@Deprecated
public int skipBytes(ChannelBufferIndexFinder firstIndexFinder) {
int oldReaderIndex = readerIndex;
int newReaderIndex = indexOf(oldReaderIndex, writerIndex, firstIndexFinder);
if (newReaderIndex < 0) {
throw new NoSuchElementException();
}
readerIndex(newReaderIndex);
return newReaderIndex - oldReaderIndex;
}
public void writeByte(int value) {//++があるから簡略化できない
setByte(writerIndex ++, value);
}
public void writeShort(int value) {
setShort(writerIndex, value);
writerIndex += 2;
}
public void writeMedium(int value) {
try{//検証
setMedium(writerIndex, value);
}catch(Exception e){
e.printStackTrace();
return;
}
writerIndex += 3;
}
public void writeInt(int value) {
setInt(writerIndex, value);
writerIndex += 4;
}
public void writeLong(long value) {
setLong(writerIndex, value);
writerIndex += 8;
}
public void writeBytes(byte[] src, int srcIndex, int length) {
setBytes(writerIndex, src, srcIndex, length);
writerIndex += length;
}
public void writeBytes(ChannelBuffer src, int length) {
if (length > src.readableBytes()) {
throw new IndexOutOfBoundsException();
}
writeBytes(src, src.readerIndex(), length);
src.readerIndex(src.readerIndex() + length);
}
public void writeBytes(ChannelBuffer src, int srcIndex, int length) {
setBytes(writerIndex, src, srcIndex, length);
writerIndex += length;
}
public void writeBytes(ByteBuffer src) {
int length = src.remaining();
setBytes(writerIndex, src);
writerIndex += length;
}
public int writeBytes(InputStream in, int length)
throws IOException {
int writtenBytes = setBytes(writerIndex, in, length);
if (writtenBytes > 0) {
writerIndex += writtenBytes;
}
return writtenBytes;
}
public int writeBytes(ScatteringByteChannel in, int length)
throws IOException {
int writtenBytes = setBytes(writerIndex, in, length);
if (writtenBytes > 0) {
writerIndex += writtenBytes;
}
return writtenBytes;
}
public void writeZero(int length) {
if (length == 0) {
return;
}
if (length < 0) {
throw new IllegalArgumentException(
"length must be 0 or greater than 0.");
}
int nLong = length >>> 3;
int nBytes = length & 7;
for (int i = nLong; i > 0; i --) {
writeLong(0);
}
if (nBytes == 4) {
writeInt(0);
} else if (nBytes < 4) {
for (int i = nBytes; i > 0; i --) {
writeByte((byte) 0);
}
} else {
writeInt(0);
for (int i = nBytes - 4; i > 0; i --) {
writeByte((byte) 0);
}
}
}
public ChannelBuffer copy() {
try{//検証
copy(readerIndex,readableBytes());
}catch(Exception e){
e.printStackTrace();
return ChannelBuffers.EMPTY_BUFFER;
}
return copy(readerIndex, readableBytes());
}
public ChannelBuffer slice() {
return slice(readerIndex, readableBytes());
}
public ByteBuffer toByteBuffer() {
return toByteBuffer(readerIndex, readableBytes());
}
public ByteBuffer[] toByteBuffers() {
return toByteBuffers(readerIndex, readableBytes());
}
public ByteBuffer[] toByteBuffers(int index, int length) {
return new ByteBuffer[] { toByteBuffer(index, length) };
}
public String toString(int index, int length, Charset charset) {
if (length == 0) {
return "";
}
return ChannelBuffers.decodeString(
toByteBuffer(index, length), charset);
}
@Deprecated
public String toString(int index, int length, String charsetName,
ChannelBufferIndexFinder terminatorFinder) {
if (terminatorFinder == null) {
return toString(index, length, charsetName);
}
int terminatorIndex = indexOf(index, index + length, terminatorFinder);
if (terminatorIndex < 0) {
return toString(index, length, charsetName);
}
return toString(index, terminatorIndex - index, charsetName);
}
@Deprecated
public String toString(int index, int length, String charsetName) {
return toString(index, length, Charset.forName(charsetName));
}
public int indexOf(int fromIndex, int toIndex, byte value) {
return ChannelBuffers.indexOf(this, fromIndex, toIndex, value);
}
public int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
return ChannelBuffers.indexOf(this, fromIndex, toIndex, indexFinder);
}
public int bytesBefore(byte value) {
return bytesBefore(readerIndex(), readableBytes(), value);
}
public int bytesBefore(ChannelBufferIndexFinder indexFinder) {
return bytesBefore(readerIndex(), readableBytes(), indexFinder);
}
public int bytesBefore(int length, byte value) {
// Log.d("bytesBefore","");
return bytesBefore(readerIndex(), length, value);
}
public int bytesBefore(int length, ChannelBufferIndexFinder indexFinder) {
// Log.d("bytesBefore","length indexFinder");
return bytesBefore(readerIndex(), length, indexFinder);
}
public int bytesBefore(int index, int length, byte value) {
int endIndex = indexOf(index, index + length, value);
if (endIndex < 0) {
return -1;
}
return endIndex - index;
}
public int bytesBefore(int index, int length,
ChannelBufferIndexFinder indexFinder) {
int endIndex = indexOf(index, index + length, indexFinder);
if (endIndex < 0) {
return -1;
}
return endIndex - index;
}
@Override
public int hashCode() {
return ChannelBuffers.hashCode(this);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ChannelBuffer)) {
return false;
}
return ChannelBuffers.equals(this, (ChannelBuffer) o);
}
public int compareTo(ChannelBuffer that) {
return ChannelBuffers.compare(this, that);
}
@Override
public String toString() {
return new StringBuilder("ridx=").append(readerIndex).append("\n")
.append("widx=").append(writerIndex).append("\n")
.append("cap=").append(capacity()).toString();
}
// /**
// * 読み込みインデックスを、書き込みインデックスが超えているかを確認
// * 超えていたらエラーにしていたが、boolean値を返す様に変更
// */
// protected boolean checkReadableBytes(int minimumReadableBytes) {
//// Log.d("AbstractChannelBuffer---","INDEX " + readableBytes()+" " + minimumReadableBytes);
// return readableBytes() < minimumReadableBytes;
// }
}