001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.util.byteaccess; 021 022import java.nio.ByteOrder; 023import java.util.Collections; 024 025import org.apache.mina.core.buffer.IoBuffer; 026 027/** 028 * A <code>ByteArray</code> backed by a <code>IoBuffer</code>. This class 029 * is abstract. Subclasses need to override the <code>free()</code> method. An 030 * implementation backed by a heap <code>IoBuffer</code> can be created with 031 * a <code>SimpleByteArrayFactory</code>. 032 * 033 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 034 */ 035public abstract class BufferByteArray extends AbstractByteArray { 036 037 /** 038 * The backing <code>IoBuffer</code>. 039 */ 040 protected IoBuffer bb; 041 042 /** 043 * 044 * Creates a new instance of BufferByteArray and uses the supplied 045 * {@link IoBuffer} to back this class 046 * 047 * @param bb 048 * The backing buffer 049 */ 050 public BufferByteArray(IoBuffer bb) { 051 this.bb = bb; 052 } 053 054 /** 055 * {@inheritDoc} 056 */ 057 public Iterable<IoBuffer> getIoBuffers() { 058 return Collections.singletonList(bb); 059 } 060 061 /** 062 * {@inheritDoc} 063 */ 064 public IoBuffer getSingleIoBuffer() { 065 return bb; 066 } 067 068 /** 069 * {@inheritDoc} 070 * 071 * Calling <code>free()</code> on the returned slice has no effect. 072 */ 073 public ByteArray slice(int index, int length) { 074 int oldLimit = bb.limit(); 075 bb.position(index); 076 bb.limit(index + length); 077 IoBuffer slice = bb.slice(); 078 bb.limit(oldLimit); 079 return new BufferByteArray(slice) { 080 081 @Override 082 public void free() { 083 // Do nothing. 084 } 085 }; 086 } 087 088 /** 089 * {@inheritDoc} 090 */ 091 public abstract void free(); 092 093 /** 094 * {@inheritDoc} 095 */ 096 public Cursor cursor() { 097 return new CursorImpl(); 098 } 099 100 /** 101 * {@inheritDoc} 102 */ 103 public Cursor cursor(int index) { 104 return new CursorImpl(index); 105 } 106 107 /** 108 * {@inheritDoc} 109 */ 110 public int first() { 111 return 0; 112 } 113 114 /** 115 * {@inheritDoc} 116 */ 117 public int last() { 118 return bb.limit(); 119 } 120 121 /** 122 * {@inheritDoc} 123 */ 124 public ByteOrder order() { 125 return bb.order(); 126 } 127 128 /** 129 * {@inheritDoc} 130 */ 131 public void order(ByteOrder order) { 132 bb.order(order); 133 } 134 135 /** 136 * {@inheritDoc} 137 */ 138 public byte get(int index) { 139 return bb.get(index); 140 } 141 142 /** 143 * {@inheritDoc} 144 */ 145 public void put(int index, byte b) { 146 bb.put(index, b); 147 } 148 149 /** 150 * {@inheritDoc} 151 */ 152 public void get(int index, IoBuffer other) { 153 bb.position(index); 154 other.put(bb); 155 } 156 157 /** 158 * {@inheritDoc} 159 */ 160 public void put(int index, IoBuffer other) { 161 bb.position(index); 162 bb.put(other); 163 } 164 165 /** 166 * {@inheritDoc} 167 */ 168 public short getShort(int index) { 169 return bb.getShort(index); 170 } 171 172 /** 173 * {@inheritDoc} 174 */ 175 public void putShort(int index, short s) { 176 bb.putShort(index, s); 177 } 178 179 /** 180 * {@inheritDoc} 181 */ 182 public int getInt(int index) { 183 return bb.getInt(index); 184 } 185 186 /** 187 * {@inheritDoc} 188 */ 189 public void putInt(int index, int i) { 190 bb.putInt(index, i); 191 } 192 193 /** 194 * {@inheritDoc} 195 */ 196 public long getLong(int index) { 197 return bb.getLong(index); 198 } 199 200 /** 201 * {@inheritDoc} 202 */ 203 public void putLong(int index, long l) { 204 bb.putLong(index, l); 205 } 206 207 /** 208 * {@inheritDoc} 209 */ 210 public float getFloat(int index) { 211 return bb.getFloat(index); 212 } 213 214 /** 215 * {@inheritDoc} 216 */ 217 public void putFloat(int index, float f) { 218 bb.putFloat(index, f); 219 } 220 221 /** 222 * {@inheritDoc} 223 */ 224 public double getDouble(int index) { 225 return bb.getDouble(index); 226 } 227 228 /** 229 * {@inheritDoc} 230 */ 231 public void putDouble(int index, double d) { 232 bb.putDouble(index, d); 233 } 234 235 /** 236 * {@inheritDoc} 237 */ 238 public char getChar(int index) { 239 return bb.getChar(index); 240 } 241 242 /** 243 * {@inheritDoc} 244 */ 245 public void putChar(int index, char c) { 246 bb.putChar(index, c); 247 } 248 249 private class CursorImpl implements Cursor { 250 251 private int index; 252 253 public CursorImpl() { 254 // This space intentionally blank. 255 } 256 257 public CursorImpl(int index) { 258 setIndex(index); 259 } 260 261 /** 262 * {@inheritDoc} 263 */ 264 public int getRemaining() { 265 return last() - index; 266 } 267 268 /** 269 * {@inheritDoc} 270 */ 271 public boolean hasRemaining() { 272 return getRemaining() > 0; 273 } 274 275 /** 276 * {@inheritDoc} 277 */ 278 public int getIndex() { 279 return index; 280 } 281 282 /** 283 * {@inheritDoc} 284 */ 285 public void setIndex(int index) { 286 if (index < 0 || index > last()) { 287 throw new IndexOutOfBoundsException(); 288 } 289 this.index = index; 290 } 291 292 public void skip(int length) { 293 setIndex(index + length); 294 } 295 296 public ByteArray slice(int length) { 297 ByteArray slice = BufferByteArray.this.slice(index, length); 298 index += length; 299 return slice; 300 } 301 302 /** 303 * {@inheritDoc} 304 */ 305 public ByteOrder order() { 306 return BufferByteArray.this.order(); 307 } 308 309 /** 310 * {@inheritDoc} 311 */ 312 public byte get() { 313 byte b = BufferByteArray.this.get(index); 314 index += 1; 315 return b; 316 } 317 318 /** 319 * {@inheritDoc} 320 */ 321 public void put(byte b) { 322 BufferByteArray.this.put(index, b); 323 index += 1; 324 } 325 326 /** 327 * {@inheritDoc} 328 */ 329 public void get(IoBuffer bb) { 330 int size = Math.min(getRemaining(), bb.remaining()); 331 BufferByteArray.this.get(index, bb); 332 index += size; 333 } 334 335 /** 336 * {@inheritDoc} 337 */ 338 public void put(IoBuffer bb) { 339 int size = bb.remaining(); 340 BufferByteArray.this.put(index, bb); 341 index += size; 342 } 343 344 /** 345 * {@inheritDoc} 346 */ 347 public short getShort() { 348 short s = BufferByteArray.this.getShort(index); 349 index += 2; 350 return s; 351 } 352 353 /** 354 * {@inheritDoc} 355 */ 356 public void putShort(short s) { 357 BufferByteArray.this.putShort(index, s); 358 index += 2; 359 } 360 361 /** 362 * {@inheritDoc} 363 */ 364 public int getInt() { 365 int i = BufferByteArray.this.getInt(index); 366 index += 4; 367 return i; 368 } 369 370 /** 371 * {@inheritDoc} 372 */ 373 public void putInt(int i) { 374 BufferByteArray.this.putInt(index, i); 375 index += 4; 376 } 377 378 /** 379 * {@inheritDoc} 380 */ 381 public long getLong() { 382 long l = BufferByteArray.this.getLong(index); 383 index += 8; 384 return l; 385 } 386 387 /** 388 * {@inheritDoc} 389 */ 390 public void putLong(long l) { 391 BufferByteArray.this.putLong(index, l); 392 index += 8; 393 } 394 395 /** 396 * {@inheritDoc} 397 */ 398 public float getFloat() { 399 float f = BufferByteArray.this.getFloat(index); 400 index += 4; 401 return f; 402 } 403 404 /** 405 * {@inheritDoc} 406 */ 407 public void putFloat(float f) { 408 BufferByteArray.this.putFloat(index, f); 409 index += 4; 410 } 411 412 /** 413 * {@inheritDoc} 414 */ 415 public double getDouble() { 416 double d = BufferByteArray.this.getDouble(index); 417 index += 8; 418 return d; 419 } 420 421 /** 422 * {@inheritDoc} 423 */ 424 public void putDouble(double d) { 425 BufferByteArray.this.putDouble(index, d); 426 index += 8; 427 } 428 429 /** 430 * {@inheritDoc} 431 */ 432 public char getChar() { 433 char c = BufferByteArray.this.getChar(index); 434 index += 2; 435 return c; 436 } 437 438 /** 439 * {@inheritDoc} 440 */ 441 public void putChar(char c) { 442 BufferByteArray.this.putChar(index, c); 443 index += 2; 444 } 445 } 446}