001 /*
002 * Copyright (C) 2008 Trustin Heuiseung Lee
003 *
004 * This library is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU Lesser General Public
006 * License as published by the Free Software Foundation; either
007 * version 2.1 of the License, or (at your option) any later version.
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this library; if not, write to the Free Software
016 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA
017 */
018 package net.gleamynode.netty.buffer;
019
020 import java.io.EOFException;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.io.OutputStream;
024 import java.nio.ByteBuffer;
025 import java.nio.channels.GatheringByteChannel;
026 import java.nio.channels.ScatteringByteChannel;
027
028 /**
029 *
030 * @author The Netty Project (netty@googlegroups.com)
031 * @author Trustin Lee (trustin@gmail.com)
032 *
033 * @version $Rev$, $Date$
034 */
035 public abstract class HeapChannelBuffer extends AbstractChannelBuffer {
036
037 protected final byte[] array;
038
039 public HeapChannelBuffer(int length) {
040 this(new byte[length], 0, 0);
041 }
042
043 public HeapChannelBuffer(byte[] array) {
044 this(array, 0, array.length);
045 }
046
047 protected HeapChannelBuffer(byte[] array, int readerIndex, int writerIndex) {
048 if (array == null) {
049 throw new NullPointerException("array");
050 }
051 this.array = array;
052 setIndex(readerIndex, writerIndex);
053 }
054
055 public int capacity() {
056 return array.length;
057 }
058
059 public byte getByte(int index) {
060 return array[index];
061 }
062
063 public void getBytes(int index, ChannelBuffer dst, int dstIndex, int length) {
064 if (dst instanceof HeapChannelBuffer) {
065 getBytes(index, ((HeapChannelBuffer) dst).array, dstIndex, length);
066 } else {
067 dst.setBytes(dstIndex, array, index, length);
068 }
069 }
070
071 public void getBytes(int index, byte[] dst, int dstIndex, int length) {
072 System.arraycopy(array, index, dst, dstIndex, length);
073 }
074
075 public void getBytes(int index, ByteBuffer dst) {
076 dst.put(array, index, Math.min(capacity() - index, dst.remaining()));
077 }
078
079 public void getBytes(int index, OutputStream out, int length)
080 throws IOException {
081 out.write(array, index, length);
082 }
083
084 public int getBytes(int index, GatheringByteChannel out, int length)
085 throws IOException {
086 return out.write(ByteBuffer.wrap(array, index, length));
087 }
088
089 public void setByte(int index, byte value) {
090 array[index] = value;
091 }
092
093 public void setBytes(int index, ChannelBuffer src, int srcIndex, int length) {
094 if (src instanceof HeapChannelBuffer) {
095 setBytes(index, ((HeapChannelBuffer) src).array, srcIndex, length);
096 } else {
097 src.getBytes(srcIndex, array, index, length);
098 }
099 }
100
101 public void setBytes(int index, byte[] src, int srcIndex, int length) {
102 System.arraycopy(src, srcIndex, array, index, length);
103 }
104
105 public void setBytes(int index, ByteBuffer src) {
106 src.get(array, index, src.remaining());
107 }
108
109 public void setBytes(int index, InputStream in, int length) throws IOException {
110 while (length > 0) {
111 int readBytes = in.read(array, index, length);
112 if (readBytes < 0) {
113 throw new EOFException();
114 }
115 index += readBytes;
116 length -= readBytes;
117 }
118 }
119
120 public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
121 ByteBuffer buf = ByteBuffer.wrap(array, index, length);
122 while (length > 0) {
123 int readBytes = in.read(buf);
124 if (readBytes < 0) {
125 throw new EOFException();
126 } else if (readBytes == 0) {
127 break;
128 }
129 }
130
131 return buf.flip().remaining();
132 }
133
134 public ChannelBuffer slice(int index, int length) {
135 if (index == 0) {
136 if (length == array.length) {
137 return duplicate();
138 } else {
139 return new TruncatedChannelBuffer(this, length);
140 }
141 } else {
142 return new SlicedChannelBuffer(this, index, length);
143 }
144 }
145
146 public ByteBuffer toByteBuffer(int index, int length) {
147 return ByteBuffer.wrap(array, index, length);
148 }
149 }