1 /* 2 * Copyright 2012 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 module hunt.net.buffer.UnpooledHeapByteBuf; 17 18 import hunt.net.buffer.AbstractByteBuf; 19 import hunt.net.buffer.AbstractReferenceCountedByteBuf; 20 import hunt.net.buffer.ByteBuf; 21 import hunt.net.buffer.ByteBufAllocator; 22 import hunt.net.buffer.ByteBufUtil; 23 import hunt.net.buffer.HeapByteBufUtil; 24 25 import hunt.Byte; 26 import hunt.io.ByteBuffer; 27 import hunt.io.BufferUtils; 28 import hunt.Exceptions; 29 import hunt.net.Exceptions; 30 import hunt.stream.Common; 31 import hunt.util.StringBuilder; 32 import hunt.util.ByteOrder; 33 34 import std.conv; 35 import std.format; 36 37 38 /** 39 * Big endian Java heap buffer implementation. It is recommended to use 40 * {@link UnpooledByteBufAllocator#heapBuffer(int, int)}, {@link Unpooled#buffer(int)} and 41 * {@link Unpooled#wrappedBuffer(byte[])} instead of calling the constructor explicitly. 42 */ 43 class UnpooledHeapByteBuf : AbstractReferenceCountedByteBuf { 44 45 private ByteBufAllocator _alloc; 46 byte[] _array; 47 private ByteBuffer tmpNioBuf; 48 49 /** 50 * Creates a new heap buffer with a newly allocated byte array. 51 * 52 * @param initialCapacity the initial capacity of the underlying byte array 53 * @param maxCapacity the max capacity of the underlying byte array 54 */ 55 this(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) { 56 super(maxCapacity); 57 58 checkNotNull(alloc, "alloc"); 59 60 if (initialCapacity > maxCapacity) { 61 throw new IllegalArgumentException(format( 62 "initialCapacity(%d) > maxCapacity(%d)", initialCapacity, maxCapacity)); 63 } 64 65 this._alloc = alloc; 66 setArray(allocateArray(initialCapacity)); 67 setIndex(0, 0); 68 } 69 70 /** 71 * Creates a new heap buffer with an existing byte array. 72 * 73 * @param initialArray the initial underlying byte array 74 * @param maxCapacity the max capacity of the underlying byte array 75 */ 76 this(ByteBufAllocator alloc, byte[] initialArray, int maxCapacity) { 77 super(maxCapacity); 78 79 checkNotNull(alloc, "alloc"); 80 checkNotNull(initialArray, "initialArray"); 81 82 if (initialArray.length > maxCapacity) { 83 throw new IllegalArgumentException(format( 84 "initialCapacity(%d) > maxCapacity(%d)", initialArray.length, maxCapacity)); 85 } 86 87 this._alloc = alloc; 88 setArray(initialArray); 89 setIndex(0, cast(int)initialArray.length); 90 } 91 92 protected byte[] allocateArray(int initialCapacity) { 93 return new byte[initialCapacity]; 94 } 95 96 protected void freeArray(byte[]) { 97 // NOOP 98 } 99 100 private void setArray(byte[] initialArray) { 101 _array = initialArray; 102 tmpNioBuf = null; 103 } 104 105 override 106 ByteBufAllocator alloc() { 107 return _alloc; 108 } 109 110 override 111 ByteOrder order() { 112 return ByteOrder.BigEndian; 113 } 114 115 override 116 bool isDirect() { 117 return false; 118 } 119 120 override 121 int capacity() { 122 return cast(int)_array.length; 123 } 124 125 override 126 ByteBuf capacity(int newCapacity) { 127 checkNewCapacity(newCapacity); 128 129 int oldCapacity = cast(int)_array.length; 130 byte[] oldArray = _array; 131 if (newCapacity > oldCapacity) { 132 byte[] newArray = allocateArray(newCapacity); 133 // System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); 134 newArray[0..oldArray.length] = oldArray[0 .. $]; 135 setArray(newArray); 136 freeArray(oldArray); 137 } else if (newCapacity < oldCapacity) { 138 byte[] newArray = allocateArray(newCapacity); 139 int rIndex = readerIndex(); 140 if (rIndex < newCapacity) { 141 int wIndex = writerIndex(); 142 if (wIndex > newCapacity) { 143 wIndex = newCapacity; 144 writerIndex(wIndex); 145 } 146 // System.arraycopy(oldArray, rIndex, newArray, rIndex, wIndex - rIndex); 147 newArray[rIndex .. wIndex] = oldArray[rIndex .. wIndex]; 148 } else { 149 setIndex(newCapacity, newCapacity); 150 } 151 setArray(newArray); 152 freeArray(oldArray); 153 } 154 return this; 155 } 156 157 override 158 bool hasArray() { 159 return true; 160 } 161 162 override 163 byte[] array() { 164 ensureAccessible(); 165 return _array; 166 } 167 168 override 169 int arrayOffset() { 170 return 0; 171 } 172 173 override 174 bool hasMemoryAddress() { 175 return false; 176 } 177 178 override 179 long memoryAddress() { 180 throw new UnsupportedOperationException(); 181 } 182 183 override 184 ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { 185 checkDstIndex(index, length, dstIndex, dst.capacity()); 186 // if (dst.hasMemoryAddress()) { 187 // PlatformDependent.copyMemory(_array, index, dst.memoryAddress() + dstIndex, length); 188 // } else if (dst.hasArray()) { 189 // getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); 190 // } else { 191 // dst.setBytes(dstIndex, _array, index, length); 192 // } 193 if (dst.hasArray()) { 194 getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); 195 } else { 196 dst.setBytes(dstIndex, _array, index, length); 197 } 198 return this; 199 } 200 201 override 202 ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { 203 checkDstIndex(index, length, dstIndex, cast(int)dst.length); 204 // System.arraycopy(_array, index, dst, dstIndex, length); 205 dst[dstIndex .. dstIndex + length] = _array[index .. index+length]; 206 return this; 207 } 208 209 override 210 ByteBuf getBytes(int index, ByteBuffer dst) { 211 ensureAccessible(); 212 dst.put(_array, index, dst.remaining()); 213 return this; 214 } 215 216 override 217 ByteBuf getBytes(int index, OutputStream output, int length) { 218 ensureAccessible(); 219 output.write(_array, index, length); 220 return this; 221 } 222 223 // override 224 // int getBytes(int index, GatheringByteChannel output, int length) { 225 // ensureAccessible(); 226 // return getBytes(index, output, length, false); 227 // } 228 229 // override 230 // int getBytes(int index, FileChannel output, long position, int length) { 231 // ensureAccessible(); 232 // return getBytes(index, output, position, length, false); 233 // } 234 235 // private int getBytes(int index, GatheringByteChannel output, int length, bool internal) { 236 // ensureAccessible(); 237 // ByteBuffer tmpBuf; 238 // if (internal) { 239 // tmpBuf = internalNioBuffer(); 240 // } else { 241 // tmpBuf = ByteBuffer.wrap(_array); 242 // } 243 // return output.write(cast(ByteBuffer) tmpBuf.clear().position(index).limit(index + length)); 244 // } 245 246 // private int getBytes(int index, FileChannel output, long position, int length, bool internal) { 247 // ensureAccessible(); 248 // ByteBuffer tmpBuf = internal ? internalNioBuffer() : ByteBuffer.wrap(_array); 249 // return output.write(cast(ByteBuffer) tmpBuf.clear().position(index).limit(index + length), position); 250 // } 251 252 // override 253 // int readBytes(GatheringByteChannel output, int length) { 254 // checkReadableBytes(length); 255 // int readBytes = getBytes(readerIndex, output, length, true); 256 // readerIndex += readBytes; 257 // return readBytes; 258 // } 259 260 // override 261 // int readBytes(FileChannel output, long position, int length) { 262 // checkReadableBytes(length); 263 // int readBytes = getBytes(readerIndex, output, position, length, true); 264 // readerIndex += readBytes; 265 // return readBytes; 266 // } 267 268 override 269 ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { 270 checkSrcIndex(index, length, srcIndex, src.capacity()); 271 // if (src.hasMemoryAddress()) { 272 // PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, _array, index, length); 273 // } else if (src.hasArray()) { 274 // setBytes(index, src.array(), src.arrayOffset() + srcIndex, length); 275 // } else { 276 // src.getBytes(srcIndex, _array, index, length); 277 // } 278 279 if (src.hasArray()) { 280 setBytes(index, src.array(), src.arrayOffset() + srcIndex, length); 281 } else { 282 src.getBytes(srcIndex, _array, index, length); 283 } 284 return this; 285 } 286 287 override 288 ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { 289 checkSrcIndex(index, length, srcIndex, cast(int)src.length); 290 // System.arraycopy(src, srcIndex, _array, index, length); 291 _array[index .. index+length] = src[srcIndex .. srcIndex+length]; 292 return this; 293 } 294 295 override 296 ByteBuf setBytes(int index, ByteBuffer src) { 297 ensureAccessible(); 298 src.get(_array, index, src.remaining()); 299 return this; 300 } 301 302 override 303 int setBytes(int index, InputStream input, int length) { 304 ensureAccessible(); 305 return input.read(_array, index, length); 306 } 307 308 // override 309 // int setBytes(int index, ScatteringByteChannel input, int length) { 310 // ensureAccessible(); 311 // try { 312 // return input.read(cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length)); 313 // } catch (ClosedChannelException ignored) { 314 // return -1; 315 // } 316 // } 317 318 // override 319 // int setBytes(int index, FileChannel input, long position, int length) { 320 // ensureAccessible(); 321 // try { 322 // return input.read(cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length), position); 323 // } catch (ClosedChannelException ignored) { 324 // return -1; 325 // } 326 // } 327 328 override 329 int nioBufferCount() { 330 return 1; 331 } 332 333 override 334 ByteBuffer nioBuffer(int index, int length) { 335 ensureAccessible(); 336 return BufferUtils.wrap(_array, index, length).slice(); 337 } 338 339 override 340 ByteBuffer[] nioBuffers(int index, int length) { 341 return [nioBuffer(index, length)]; 342 } 343 344 override 345 ByteBuffer internalNioBuffer(int index, int length) { 346 checkIndex(index, length); 347 return cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); 348 } 349 350 override 351 byte getByte(int index) { 352 ensureAccessible(); 353 return _getByte(index); 354 } 355 356 override 357 protected byte _getByte(int index) { 358 return HeapByteBufUtil.getByte(_array, index); 359 } 360 361 override 362 short getShort(int index) { 363 ensureAccessible(); 364 return _getShort(index); 365 } 366 367 override 368 protected short _getShort(int index) { 369 return HeapByteBufUtil.getShort(_array, index); 370 } 371 372 override 373 short getShortLE(int index) { 374 ensureAccessible(); 375 return _getShortLE(index); 376 } 377 378 override 379 protected short _getShortLE(int index) { 380 return HeapByteBufUtil.getShortLE(_array, index); 381 } 382 383 override 384 int getUnsignedMedium(int index) { 385 ensureAccessible(); 386 return _getUnsignedMedium(index); 387 } 388 389 override 390 protected int _getUnsignedMedium(int index) { 391 return HeapByteBufUtil.getUnsignedMedium(_array, index); 392 } 393 394 override 395 int getUnsignedMediumLE(int index) { 396 ensureAccessible(); 397 return _getUnsignedMediumLE(index); 398 } 399 400 override 401 protected int _getUnsignedMediumLE(int index) { 402 return HeapByteBufUtil.getUnsignedMediumLE(_array, index); 403 } 404 405 override 406 int getInt(int index) { 407 ensureAccessible(); 408 return _getInt(index); 409 } 410 411 override 412 protected int _getInt(int index) { 413 return HeapByteBufUtil.getInt(_array, index); 414 } 415 416 override 417 int getIntLE(int index) { 418 ensureAccessible(); 419 return _getIntLE(index); 420 } 421 422 override 423 protected int _getIntLE(int index) { 424 return HeapByteBufUtil.getIntLE(_array, index); 425 } 426 427 override 428 long getLong(int index) { 429 ensureAccessible(); 430 return _getLong(index); 431 } 432 433 override 434 protected long _getLong(int index) { 435 return HeapByteBufUtil.getLong(_array, index); 436 } 437 438 override 439 long getLongLE(int index) { 440 ensureAccessible(); 441 return _getLongLE(index); 442 } 443 444 override 445 protected long _getLongLE(int index) { 446 return HeapByteBufUtil.getLongLE(_array, index); 447 } 448 449 override 450 ByteBuf setByte(int index, int value) { 451 ensureAccessible(); 452 _setByte(index, value); 453 return this; 454 } 455 456 override 457 protected void _setByte(int index, int value) { 458 HeapByteBufUtil.setByte(_array, index, value); 459 } 460 461 override 462 ByteBuf setShort(int index, int value) { 463 ensureAccessible(); 464 _setShort(index, value); 465 return this; 466 } 467 468 override 469 protected void _setShort(int index, int value) { 470 HeapByteBufUtil.setShort(_array, index, value); 471 } 472 473 override 474 ByteBuf setShortLE(int index, int value) { 475 ensureAccessible(); 476 _setShortLE(index, value); 477 return this; 478 } 479 480 override 481 protected void _setShortLE(int index, int value) { 482 HeapByteBufUtil.setShortLE(_array, index, value); 483 } 484 485 override 486 ByteBuf setMedium(int index, int value) { 487 ensureAccessible(); 488 _setMedium(index, value); 489 return this; 490 } 491 492 override 493 protected void _setMedium(int index, int value) { 494 HeapByteBufUtil.setMedium(_array, index, value); 495 } 496 497 override 498 ByteBuf setMediumLE(int index, int value) { 499 ensureAccessible(); 500 _setMediumLE(index, value); 501 return this; 502 } 503 504 override 505 protected void _setMediumLE(int index, int value) { 506 HeapByteBufUtil.setMediumLE(_array, index, value); 507 } 508 509 override 510 ByteBuf setInt(int index, int value) { 511 ensureAccessible(); 512 _setInt(index, value); 513 return this; 514 } 515 516 override 517 protected void _setInt(int index, int value) { 518 HeapByteBufUtil.setInt(_array, index, value); 519 } 520 521 override 522 ByteBuf setIntLE(int index, int value) { 523 ensureAccessible(); 524 _setIntLE(index, value); 525 return this; 526 } 527 528 override 529 protected void _setIntLE(int index, int value) { 530 HeapByteBufUtil.setIntLE(_array, index, value); 531 } 532 533 override 534 ByteBuf setLong(int index, long value) { 535 ensureAccessible(); 536 _setLong(index, value); 537 return this; 538 } 539 540 override 541 protected void _setLong(int index, long value) { 542 HeapByteBufUtil.setLong(_array, index, value); 543 } 544 545 override 546 ByteBuf setLongLE(int index, long value) { 547 ensureAccessible(); 548 _setLongLE(index, value); 549 return this; 550 } 551 552 override 553 protected void _setLongLE(int index, long value) { 554 HeapByteBufUtil.setLongLE(_array, index, value); 555 } 556 557 override 558 ByteBuf copy(int index, int length) { 559 checkIndex(index, length); 560 return alloc().heapBuffer(length, maxCapacity()).writeBytes(_array, index, length); 561 } 562 563 private ByteBuffer internalNioBuffer() { 564 ByteBuffer tmpNioBuf = this.tmpNioBuf; 565 if (tmpNioBuf is null) { 566 this.tmpNioBuf = tmpNioBuf = BufferUtils.wrap(_array); 567 } 568 return tmpNioBuf; 569 } 570 571 override 572 protected void deallocate() { 573 freeArray(_array); 574 _array = []; 575 } 576 577 override 578 ByteBuf unwrap() { 579 return null; 580 } 581 }