1 /* 2 * Copyright 2013 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.FixedCompositeByteBuf; 17 18 import hunt.net.buffer.AbstractReferenceCountedByteBuf; 19 import hunt.net.buffer.ByteBuf; 20 import hunt.net.buffer.ByteBufUtil; 21 import hunt.net.buffer.Unpooled; 22 import hunt.net.buffer.WrappedByteBuf; 23 24 import hunt.io.ByteBuffer; 25 import hunt.Exceptions; 26 import hunt.net.Exceptions; 27 import hunt.stream.Common; 28 import hunt.util.StringBuilder; 29 import hunt.util.Common; 30 31 import std.conv; 32 import std.format; 33 import std.concurrency : initOnce; 34 35 // import io.netty.util.internal.EmptyArrays; 36 // import io.netty.util.internal.RecyclableArrayList; 37 38 // import java.io.IOException; 39 // import java.io.InputStream; 40 // import java.io.OutputStream; 41 // import java.nio.ByteBuffer; 42 // import java.nio.ByteOrder; 43 // import java.nio.ReadOnlyBufferException; 44 // import java.nio.channels.FileChannel; 45 // import java.nio.channels.GatheringByteChannel; 46 // import java.nio.channels.ScatteringByteChannel; 47 // import java.util.Collections; 48 49 /** 50 * {@link ByteBuf} implementation which allows to wrap an array of {@link ByteBuf} in a read-only mode. 51 * This is useful to write an array of {@link ByteBuf}s. 52 */ 53 // final class FixedCompositeByteBuf : AbstractReferenceCountedByteBuf { 54 // private __gshared ByteBuf[] EMPTY() { 55 // return [Unpooled.EMPTY_BUFFER()]; 56 // } 57 58 // private int nioBufferCount; 59 // private int capacity; 60 // private ByteBufAllocator allocator; 61 // private ByteOrder order; 62 // private ByteBuf[] buffers; 63 // private boolean direct; 64 65 // this(ByteBufAllocator allocator, ByteBuf[] buffers...) { 66 // super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY); 67 // if (buffers.length == 0) { 68 // this.buffers = EMPTY; 69 // order = ByteProcessor; 70 // nioBufferCount = 1; 71 // capacity = 0; 72 // direct = false; 73 // } else { 74 // ByteBuf b = buffers[0]; 75 // this.buffers = buffers; 76 // boolean direct = true; 77 // int nioBufferCount = b.nioBufferCount(); 78 // int capacity = b.readableBytes(); 79 // order = b.order(); 80 // for (int i = 1; i < buffers.length; i++) { 81 // b = buffers[i]; 82 // if (buffers[i].order() != order) { 83 // throw new IllegalArgumentException("All ByteBufs need to have same ByteOrder"); 84 // } 85 // nioBufferCount += b.nioBufferCount(); 86 // capacity += b.readableBytes(); 87 // if (!b.isDirect()) { 88 // direct = false; 89 // } 90 // } 91 // this.nioBufferCount = nioBufferCount; 92 // this.capacity = capacity; 93 // this.direct = direct; 94 // } 95 // setIndex(0, capacity()); 96 // this.allocator = allocator; 97 // } 98 99 // override 100 // boolean isWritable() { 101 // return false; 102 // } 103 104 // override 105 // boolean isWritable(int size) { 106 // return false; 107 // } 108 109 // override 110 // ByteBuf discardReadBytes() { 111 // throw new ReadOnlyBufferException(); 112 // } 113 114 // override 115 // ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { 116 // throw new ReadOnlyBufferException(); 117 // } 118 119 // override 120 // ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { 121 // throw new ReadOnlyBufferException(); 122 // } 123 124 // override 125 // ByteBuf setBytes(int index, ByteBuffer src) { 126 // throw new ReadOnlyBufferException(); 127 // } 128 129 // override 130 // ByteBuf setByte(int index, int value) { 131 // throw new ReadOnlyBufferException(); 132 // } 133 134 // override 135 // protected void _setByte(int index, int value) { 136 // throw new ReadOnlyBufferException(); 137 // } 138 139 // override 140 // ByteBuf setShort(int index, int value) { 141 // throw new ReadOnlyBufferException(); 142 // } 143 144 // override 145 // protected void _setShort(int index, int value) { 146 // throw new ReadOnlyBufferException(); 147 // } 148 149 // override 150 // protected void _setShortLE(int index, int value) { 151 // throw new ReadOnlyBufferException(); 152 // } 153 154 // override 155 // ByteBuf setMedium(int index, int value) { 156 // throw new ReadOnlyBufferException(); 157 // } 158 159 // override 160 // protected void _setMedium(int index, int value) { 161 // throw new ReadOnlyBufferException(); 162 // } 163 164 // override 165 // protected void _setMediumLE(int index, int value) { 166 // throw new ReadOnlyBufferException(); 167 // } 168 169 // override 170 // ByteBuf setInt(int index, int value) { 171 // throw new ReadOnlyBufferException(); 172 // } 173 174 // override 175 // protected void _setInt(int index, int value) { 176 // throw new ReadOnlyBufferException(); 177 // } 178 179 // override 180 // protected void _setIntLE(int index, int value) { 181 // throw new ReadOnlyBufferException(); 182 // } 183 184 // override 185 // ByteBuf setLong(int index, long value) { 186 // throw new ReadOnlyBufferException(); 187 // } 188 189 // override 190 // protected void _setLong(int index, long value) { 191 // throw new ReadOnlyBufferException(); 192 // } 193 194 // override 195 // protected void _setLongLE(int index, long value) { 196 // throw new ReadOnlyBufferException(); 197 // } 198 199 // override 200 // int setBytes(int index, InputStream in, int length) { 201 // throw new ReadOnlyBufferException(); 202 // } 203 204 // override 205 // int setBytes(int index, ScatteringByteChannel in, int length) { 206 // throw new ReadOnlyBufferException(); 207 // } 208 209 // override 210 // int setBytes(int index, FileChannel in, long position, int length) { 211 // throw new ReadOnlyBufferException(); 212 // } 213 214 // override 215 // int capacity() { 216 // return capacity; 217 // } 218 219 // override 220 // int maxCapacity() { 221 // return capacity; 222 // } 223 224 // override 225 // ByteBuf capacity(int newCapacity) { 226 // throw new ReadOnlyBufferException(); 227 // } 228 229 // override 230 // ByteBufAllocator alloc() { 231 // return allocator; 232 // } 233 234 // override 235 // ByteOrder order() { 236 // return order; 237 // } 238 239 // override 240 // ByteBuf unwrap() { 241 // return null; 242 // } 243 244 // override 245 // boolean isDirect() { 246 // return direct; 247 // } 248 249 // private Component findComponent(int index) { 250 // int readable = 0; 251 // for (int i = 0 ; i < buffers.length; i++) { 252 // Component comp = null; 253 // ByteBuf b = buffers[i]; 254 // if (b instanceof Component) { 255 // comp = (Component) b; 256 // b = comp.buf; 257 // } 258 // readable += b.readableBytes(); 259 // if (index < readable) { 260 // if (comp is null) { 261 // // Create a new component and store it in the array so it not create a new object 262 // // on the next access. 263 // comp = new Component(i, readable - b.readableBytes(), b); 264 // buffers[i] = comp; 265 // } 266 // return comp; 267 // } 268 // } 269 // throw new IllegalStateException(); 270 // } 271 272 // /** 273 // * Return the {@link ByteBuf} stored at the given index of the array. 274 // */ 275 // private ByteBuf buffer(int i) { 276 // ByteBuf b = buffers[i]; 277 // return b instanceof Component ? ((Component) b).buf : b; 278 // } 279 280 // override 281 // byte getByte(int index) { 282 // return _getByte(index); 283 // } 284 285 // override 286 // protected byte _getByte(int index) { 287 // Component c = findComponent(index); 288 // return c.buf.getByte(index - c.offset); 289 // } 290 291 // override 292 // protected short _getShort(int index) { 293 // Component c = findComponent(index); 294 // if (index + 2 <= c.endOffset) { 295 // return c.buf.getShort(index - c.offset); 296 // } else if (order() == ByteProcessor) { 297 // return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff); 298 // } else { 299 // return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8); 300 // } 301 // } 302 303 // override 304 // protected short _getShortLE(int index) { 305 // Component c = findComponent(index); 306 // if (index + 2 <= c.endOffset) { 307 // return c.buf.getShortLE(index - c.offset); 308 // } else if (order() == ByteProcessor) { 309 // return (short) (_getByte(index) & 0xff | (_getByte(index + 1) & 0xff) << 8); 310 // } else { 311 // return (short) ((_getByte(index) & 0xff) << 8 | _getByte(index + 1) & 0xff); 312 // } 313 // } 314 315 // override 316 // protected int _getUnsignedMedium(int index) { 317 // Component c = findComponent(index); 318 // if (index + 3 <= c.endOffset) { 319 // return c.buf.getUnsignedMedium(index - c.offset); 320 // } else if (order() == ByteProcessor) { 321 // return (_getShort(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff; 322 // } else { 323 // return _getShort(index) & 0xFFFF | (_getByte(index + 2) & 0xFF) << 16; 324 // } 325 // } 326 327 // override 328 // protected int _getUnsignedMediumLE(int index) { 329 // Component c = findComponent(index); 330 // if (index + 3 <= c.endOffset) { 331 // return c.buf.getUnsignedMediumLE(index - c.offset); 332 // } else if (order() == ByteProcessor) { 333 // return _getShortLE(index) & 0xffff | (_getByte(index + 2) & 0xff) << 16; 334 // } else { 335 // return (_getShortLE(index) & 0xffff) << 8 | _getByte(index + 2) & 0xff; 336 // } 337 // } 338 339 // override 340 // protected int _getInt(int index) { 341 // Component c = findComponent(index); 342 // if (index + 4 <= c.endOffset) { 343 // return c.buf.getInt(index - c.offset); 344 // } else if (order() == ByteProcessor) { 345 // return (_getShort(index) & 0xffff) << 16 | _getShort(index + 2) & 0xffff; 346 // } else { 347 // return _getShort(index) & 0xFFFF | (_getShort(index + 2) & 0xFFFF) << 16; 348 // } 349 // } 350 351 // override 352 // protected int _getIntLE(int index) { 353 // Component c = findComponent(index); 354 // if (index + 4 <= c.endOffset) { 355 // return c.buf.getIntLE(index - c.offset); 356 // } else if (order() == ByteProcessor) { 357 // return _getShortLE(index) & 0xFFFF | (_getShortLE(index + 2) & 0xFFFF) << 16; 358 // } else { 359 // return (_getShortLE(index) & 0xffff) << 16 | _getShortLE(index + 2) & 0xffff; 360 // } 361 // } 362 363 // override 364 // protected long _getLong(int index) { 365 // Component c = findComponent(index); 366 // if (index + 8 <= c.endOffset) { 367 // return c.buf.getLong(index - c.offset); 368 // } else if (order() == ByteProcessor) { 369 // return (_getInt(index) & 0xffffffffL) << 32 | _getInt(index + 4) & 0xffffffffL; 370 // } else { 371 // return _getInt(index) & 0xFFFFFFFFL | (_getInt(index + 4) & 0xFFFFFFFFL) << 32; 372 // } 373 // } 374 375 // override 376 // protected long _getLongLE(int index) { 377 // Component c = findComponent(index); 378 // if (index + 8 <= c.endOffset) { 379 // return c.buf.getLongLE(index - c.offset); 380 // } else if (order() == ByteProcessor) { 381 // return _getIntLE(index) & 0xffffffffL | (_getIntLE(index + 4) & 0xffffffffL) << 32; 382 // } else { 383 // return (_getIntLE(index) & 0xffffffffL) << 32 | _getIntLE(index + 4) & 0xffffffffL; 384 // } 385 // } 386 387 // override 388 // ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { 389 // checkDstIndex(index, length, dstIndex, dst.length); 390 // if (length == 0) { 391 // return this; 392 // } 393 394 // Component c = findComponent(index); 395 // int i = c.index; 396 // int adjustment = c.offset; 397 // ByteBuf s = c.buf; 398 // for (;;) { 399 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment)); 400 // s.getBytes(index - adjustment, dst, dstIndex, localLength); 401 // index += localLength; 402 // dstIndex += localLength; 403 // length -= localLength; 404 // adjustment += s.readableBytes(); 405 // if (length <= 0) { 406 // break; 407 // } 408 // s = buffer(++i); 409 // } 410 // return this; 411 // } 412 413 // override 414 // ByteBuf getBytes(int index, ByteBuffer dst) { 415 // int limit = dst.limit(); 416 // int length = dst.remaining(); 417 418 // checkIndex(index, length); 419 // if (length == 0) { 420 // return this; 421 // } 422 423 // try { 424 // Component c = findComponent(index); 425 // int i = c.index; 426 // int adjustment = c.offset; 427 // ByteBuf s = c.buf; 428 // for (;;) { 429 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment)); 430 // dst.limit(dst.position() + localLength); 431 // s.getBytes(index - adjustment, dst); 432 // index += localLength; 433 // length -= localLength; 434 // adjustment += s.readableBytes(); 435 // if (length <= 0) { 436 // break; 437 // } 438 // s = buffer(++i); 439 // } 440 // } finally { 441 // dst.limit(limit); 442 // } 443 // return this; 444 // } 445 446 // override 447 // ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { 448 // checkDstIndex(index, length, dstIndex, dst.capacity()); 449 // if (length == 0) { 450 // return this; 451 // } 452 453 // Component c = findComponent(index); 454 // int i = c.index; 455 // int adjustment = c.offset; 456 // ByteBuf s = c.buf; 457 // for (;;) { 458 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment)); 459 // s.getBytes(index - adjustment, dst, dstIndex, localLength); 460 // index += localLength; 461 // dstIndex += localLength; 462 // length -= localLength; 463 // adjustment += s.readableBytes(); 464 // if (length <= 0) { 465 // break; 466 // } 467 // s = buffer(++i); 468 // } 469 // return this; 470 // } 471 472 // override 473 // int getBytes(int index, GatheringByteChannel out, int length) { 474 // int count = nioBufferCount(); 475 // if (count == 1) { 476 // return out.write(internalNioBuffer(index, length)); 477 // } else { 478 // long writtenBytes = out.write(nioBuffers(index, length)); 479 // if (writtenBytes > Integer.MAX_VALUE) { 480 // return Integer.MAX_VALUE; 481 // } else { 482 // return (int) writtenBytes; 483 // } 484 // } 485 // } 486 487 // override 488 // int getBytes(int index, FileChannel out, long position, int length) { 489 // int count = nioBufferCount(); 490 // if (count == 1) { 491 // return out.write(internalNioBuffer(index, length), position); 492 // } else { 493 // long writtenBytes = 0; 494 // foreach(ByteBuffer buf ; nioBuffers(index, length)) { 495 // writtenBytes += out.write(buf, position + writtenBytes); 496 // } 497 // if (writtenBytes > Integer.MAX_VALUE) { 498 // return Integer.MAX_VALUE; 499 // } else { 500 // return (int) writtenBytes; 501 // } 502 // } 503 // } 504 505 // override 506 // ByteBuf getBytes(int index, OutputStream out, int length) { 507 // checkIndex(index, length); 508 // if (length == 0) { 509 // return this; 510 // } 511 512 // Component c = findComponent(index); 513 // int i = c.index; 514 // int adjustment = c.offset; 515 // ByteBuf s = c.buf; 516 // for (;;) { 517 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment)); 518 // s.getBytes(index - adjustment, out, localLength); 519 // index += localLength; 520 // length -= localLength; 521 // adjustment += s.readableBytes(); 522 // if (length <= 0) { 523 // break; 524 // } 525 // s = buffer(++i); 526 // } 527 // return this; 528 // } 529 530 // override 531 // ByteBuf copy(int index, int length) { 532 // checkIndex(index, length); 533 // boolean release = true; 534 // ByteBuf buf = alloc().buffer(length); 535 // try { 536 // buf.writeBytes(this, index, length); 537 // release = false; 538 // return buf; 539 // } finally { 540 // if (release) { 541 // buf.release(); 542 // } 543 // } 544 // } 545 546 // override 547 // int nioBufferCount() { 548 // return nioBufferCount; 549 // } 550 551 // override 552 // ByteBuffer nioBuffer(int index, int length) { 553 // checkIndex(index, length); 554 // if (buffers.length == 1) { 555 // ByteBuf buf = buffer(0); 556 // if (buf.nioBufferCount() == 1) { 557 // return buf.nioBuffer(index, length); 558 // } 559 // } 560 // ByteBuffer merged = ByteBuffer.allocate(length).order(order()); 561 // ByteBuffer[] buffers = nioBuffers(index, length); 562 563 // //noinspection ForLoopReplaceableByForEach 564 // for (int i = 0; i < buffers.length; i++) { 565 // merged.put(buffers[i]); 566 // } 567 568 // merged.flip(); 569 // return merged; 570 // } 571 572 // override 573 // ByteBuffer internalNioBuffer(int index, int length) { 574 // if (buffers.length == 1) { 575 // return buffer(0).internalNioBuffer(index, length); 576 // } 577 // throw new UnsupportedOperationException(); 578 // } 579 580 // override 581 // ByteBuffer[] nioBuffers(int index, int length) { 582 // checkIndex(index, length); 583 // if (length == 0) { 584 // return EmptyArrays.EMPTY_BYTE_BUFFERS; 585 // } 586 587 // RecyclableArrayList array = RecyclableArrayList.newInstance(buffers.length); 588 // try { 589 // Component c = findComponent(index); 590 // int i = c.index; 591 // int adjustment = c.offset; 592 // ByteBuf s = c.buf; 593 // for (;;) { 594 // int localLength = Math.min(length, s.readableBytes() - (index - adjustment)); 595 // switch (s.nioBufferCount()) { 596 // case 0: 597 // throw new UnsupportedOperationException(); 598 // case 1: 599 // array.add(s.nioBuffer(index - adjustment, localLength)); 600 // break; 601 // default: 602 // Collections.addAll(array, s.nioBuffers(index - adjustment, localLength)); 603 // } 604 605 // index += localLength; 606 // length -= localLength; 607 // adjustment += s.readableBytes(); 608 // if (length <= 0) { 609 // break; 610 // } 611 // s = buffer(++i); 612 // } 613 614 // return array.toArray(new ByteBuffer[0]); 615 // } finally { 616 // array.recycle(); 617 // } 618 // } 619 620 // override 621 // boolean hasArray() { 622 // switch (buffers.length) { 623 // case 0: 624 // return true; 625 // case 1: 626 // return buffer(0).hasArray(); 627 // default: 628 // return false; 629 // } 630 // } 631 632 // override 633 // byte[] array() { 634 // switch (buffers.length) { 635 // case 0: 636 // return EmptyArrays.EMPTY_BYTES; 637 // case 1: 638 // return buffer(0).array(); 639 // default: 640 // throw new UnsupportedOperationException(); 641 // } 642 // } 643 644 // override 645 // int arrayOffset() { 646 // switch (buffers.length) { 647 // case 0: 648 // return 0; 649 // case 1: 650 // return buffer(0).arrayOffset(); 651 // default: 652 // throw new UnsupportedOperationException(); 653 // } 654 // } 655 656 // override 657 // boolean hasMemoryAddress() { 658 // switch (buffers.length) { 659 // case 0: 660 // return Unpooled.EMPTY_BUFFER.hasMemoryAddress(); 661 // case 1: 662 // return buffer(0).hasMemoryAddress(); 663 // default: 664 // return false; 665 // } 666 // } 667 668 // override 669 // long memoryAddress() { 670 // switch (buffers.length) { 671 // case 0: 672 // return Unpooled.EMPTY_BUFFER.memoryAddress(); 673 // case 1: 674 // return buffer(0).memoryAddress(); 675 // default: 676 // throw new UnsupportedOperationException(); 677 // } 678 // } 679 680 // override 681 // protected void deallocate() { 682 // for (int i = 0; i < buffers.length; i++) { 683 // buffer(i).release(); 684 // } 685 // } 686 687 // override 688 // string toString() { 689 // string result = super.toString(); 690 // result = result.substring(0, result.length() - 1); 691 // return result ~ ", components=" ~ buffers.length + ')'; 692 // } 693 // } 694 695 696 697 private static final class Component : WrappedByteBuf { 698 private int index; 699 private int offset; 700 private int endOffset; 701 702 this(int index, int offset, ByteBuf buf) { 703 super(buf); 704 this.index = index; 705 this.offset = offset; 706 endOffset = offset + buf.readableBytes(); 707 } 708 }