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.ReadOnlyByteBufferBuf; 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 24 import hunt.Byte; 25 import hunt.io.ByteBuffer; 26 import hunt.Exceptions; 27 import hunt.net.Exceptions; 28 import hunt.stream.Common; 29 import hunt.util.StringBuilder; 30 import hunt.util.ByteOrder; 31 32 import std.conv; 33 import std.format; 34 35 36 /** 37 * Read-only ByteBuf which wraps a read-only ByteBuffer. 38 */ 39 class ReadOnlyByteBufferBuf : AbstractReferenceCountedByteBuf { 40 41 protected ByteBuffer buffer; 42 private ByteBufAllocator allocator; 43 private ByteBuffer tmpNioBuf; 44 45 this(ByteBufAllocator allocator, ByteBuffer buffer) { 46 super(buffer.remaining()); 47 if (!buffer.isReadOnly()) { 48 throw new IllegalArgumentException("must be a readonly buffer: " ~ typeid(buffer).name); 49 } 50 51 this.allocator = allocator; 52 this.buffer = buffer.slice().order(ByteOrder.BigEndian); 53 writerIndex(this.buffer.limit()); 54 } 55 56 override 57 protected void deallocate() { } 58 59 override 60 bool isWritable() { 61 return false; 62 } 63 64 override 65 bool isWritable(int numBytes) { 66 return false; 67 } 68 69 override 70 ByteBuf ensureWritable(int minWritableBytes) { 71 throw new ReadOnlyBufferException(); 72 } 73 74 override 75 int ensureWritable(int minWritableBytes, bool force) { 76 return 1; 77 } 78 79 override 80 byte getByte(int index) { 81 ensureAccessible(); 82 return _getByte(index); 83 } 84 85 override 86 protected byte _getByte(int index) { 87 return buffer.get(index); 88 } 89 90 override 91 short getShort(int index) { 92 ensureAccessible(); 93 return _getShort(index); 94 } 95 96 override 97 protected short _getShort(int index) { 98 return buffer.getShort(index); 99 } 100 101 override 102 short getShortLE(int index) { 103 ensureAccessible(); 104 return _getShortLE(index); 105 } 106 107 override 108 protected short _getShortLE(int index) { 109 return ByteBufUtil.swapShort(buffer.getShort(index)); 110 } 111 112 override 113 int getUnsignedMedium(int index) { 114 ensureAccessible(); 115 return _getUnsignedMedium(index); 116 } 117 118 override 119 protected int _getUnsignedMedium(int index) { 120 return (getByte(index) & 0xff) << 16 | 121 (getByte(index + 1) & 0xff) << 8 | 122 getByte(index + 2) & 0xff; 123 } 124 125 override 126 int getUnsignedMediumLE(int index) { 127 ensureAccessible(); 128 return _getUnsignedMediumLE(index); 129 } 130 131 override 132 protected int _getUnsignedMediumLE(int index) { 133 return getByte(index) & 0xff | 134 (getByte(index + 1) & 0xff) << 8 | 135 (getByte(index + 2) & 0xff) << 16; 136 } 137 138 override 139 int getInt(int index) { 140 ensureAccessible(); 141 return _getInt(index); 142 } 143 144 override 145 protected int _getInt(int index) { 146 return buffer.getInt(index); 147 } 148 149 override 150 int getIntLE(int index) { 151 ensureAccessible(); 152 return _getIntLE(index); 153 } 154 155 override 156 protected int _getIntLE(int index) { 157 return ByteBufUtil.swapInt(buffer.getInt(index)); 158 } 159 160 override 161 long getLong(int index) { 162 ensureAccessible(); 163 return _getLong(index); 164 } 165 166 override 167 protected long _getLong(int index) { 168 return buffer.getLong(index); 169 } 170 171 override 172 long getLongLE(int index) { 173 ensureAccessible(); 174 return _getLongLE(index); 175 } 176 177 override 178 protected long _getLongLE(int index) { 179 return ByteBufUtil.swapLong(buffer.getLong(index)); 180 } 181 182 override 183 ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { 184 checkDstIndex(index, length, dstIndex, dst.capacity()); 185 if (dst.hasArray()) { 186 getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length); 187 } else if (dst.nioBufferCount() > 0) { 188 foreach(ByteBuffer bb; dst.nioBuffers(dstIndex, length)) { 189 int bbLen = bb.remaining(); 190 getBytes(index, bb); 191 index += bbLen; 192 } 193 } else { 194 dst.setBytes(dstIndex, this, index, length); 195 } 196 return this; 197 } 198 199 override 200 ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { 201 checkDstIndex(index, length, dstIndex, cast(int)dst.length); 202 203 ByteBuffer tmpBuf = internalNioBuffer(); 204 tmpBuf.clear().position(index).limit(index + length); 205 tmpBuf.get(dst, dstIndex, length); 206 return this; 207 } 208 209 override 210 ByteBuf getBytes(int index, ByteBuffer dst) { 211 checkIndex(index, dst.remaining()); 212 213 ByteBuffer tmpBuf = internalNioBuffer(); 214 tmpBuf.clear().position(index).limit(index + dst.remaining()); 215 dst.put(tmpBuf); 216 return this; 217 } 218 219 override 220 ByteBuf setByte(int index, int value) { 221 throw new ReadOnlyBufferException(); 222 } 223 224 override 225 protected void _setByte(int index, int value) { 226 throw new ReadOnlyBufferException(); 227 } 228 229 override 230 ByteBuf setShort(int index, int value) { 231 throw new ReadOnlyBufferException(); 232 } 233 234 override 235 protected void _setShort(int index, int value) { 236 throw new ReadOnlyBufferException(); 237 } 238 239 override 240 ByteBuf setShortLE(int index, int value) { 241 throw new ReadOnlyBufferException(); 242 } 243 244 override 245 protected void _setShortLE(int index, int value) { 246 throw new ReadOnlyBufferException(); 247 } 248 249 override 250 ByteBuf setMedium(int index, int value) { 251 throw new ReadOnlyBufferException(); 252 } 253 254 override 255 protected void _setMedium(int index, int value) { 256 throw new ReadOnlyBufferException(); 257 } 258 259 override 260 ByteBuf setMediumLE(int index, int value) { 261 throw new ReadOnlyBufferException(); 262 } 263 264 override 265 protected void _setMediumLE(int index, int value) { 266 throw new ReadOnlyBufferException(); 267 } 268 269 override 270 ByteBuf setInt(int index, int value) { 271 throw new ReadOnlyBufferException(); 272 } 273 274 override 275 protected void _setInt(int index, int value) { 276 throw new ReadOnlyBufferException(); 277 } 278 279 override 280 ByteBuf setIntLE(int index, int value) { 281 throw new ReadOnlyBufferException(); 282 } 283 284 override 285 protected void _setIntLE(int index, int value) { 286 throw new ReadOnlyBufferException(); 287 } 288 289 override 290 ByteBuf setLong(int index, long value) { 291 throw new ReadOnlyBufferException(); 292 } 293 294 override 295 protected void _setLong(int index, long value) { 296 throw new ReadOnlyBufferException(); 297 } 298 299 override 300 ByteBuf setLongLE(int index, long value) { 301 throw new ReadOnlyBufferException(); 302 } 303 304 override 305 protected void _setLongLE(int index, long value) { 306 throw new ReadOnlyBufferException(); 307 } 308 309 override 310 int capacity() { 311 return maxCapacity(); 312 } 313 314 override 315 ByteBuf capacity(int newCapacity) { 316 throw new ReadOnlyBufferException(); 317 } 318 319 override 320 ByteBufAllocator alloc() { 321 return allocator; 322 } 323 324 override 325 ByteOrder order() { 326 return ByteOrder.BigEndian; 327 } 328 329 override 330 ByteBuf unwrap() { 331 return null; 332 } 333 334 override 335 bool isReadOnly() { 336 return buffer.isReadOnly(); 337 } 338 339 override 340 bool isDirect() { 341 return buffer.isDirect(); 342 } 343 344 override 345 ByteBuf getBytes(int index, OutputStream output, int length) { 346 ensureAccessible(); 347 if (length == 0) { 348 return this; 349 } 350 351 if (buffer.hasArray()) { 352 output.write(buffer.array(), index + buffer.arrayOffset(), length); 353 } else { 354 byte[] tmp = ByteBufUtil.threadLocalTempArray(length); 355 ByteBuffer tmpBuf = internalNioBuffer(); 356 tmpBuf.clear().position(index); 357 tmpBuf.get(tmp, 0, length); 358 output.write(tmp, 0, length); 359 } 360 return this; 361 } 362 363 // override 364 // int getBytes(int index, GatheringByteChannel output, int length) { 365 // ensureAccessible(); 366 // if (length == 0) { 367 // return 0; 368 // } 369 370 // ByteBuffer tmpBuf = internalNioBuffer(); 371 // tmpBuf.clear().position(index).limit(index + length); 372 // return output.write(tmpBuf); 373 // } 374 375 // override 376 // int getBytes(int index, FileChannel output, long position, int length) { 377 // ensureAccessible(); 378 // if (length == 0) { 379 // return 0; 380 // } 381 382 // ByteBuffer tmpBuf = internalNioBuffer(); 383 // tmpBuf.clear().position(index).limit(index + length); 384 // return output.write(tmpBuf, position); 385 // } 386 387 override 388 ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { 389 throw new ReadOnlyBufferException(); 390 } 391 392 override 393 ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { 394 throw new ReadOnlyBufferException(); 395 } 396 397 override 398 ByteBuf setBytes(int index, ByteBuffer src) { 399 throw new ReadOnlyBufferException(); 400 } 401 402 override 403 int setBytes(int index, InputStream input, int length) { 404 throw new ReadOnlyBufferException(); 405 } 406 407 // override 408 // int setBytes(int index, ScatteringByteChannel input, int length) { 409 // throw new ReadOnlyBufferException(); 410 // } 411 412 // override 413 // int setBytes(int index, FileChannel input, long position, int length) { 414 // throw new ReadOnlyBufferException(); 415 // } 416 417 protected final ByteBuffer internalNioBuffer() { 418 ByteBuffer tmpNioBuf = this.tmpNioBuf; 419 if (tmpNioBuf is null) { 420 this.tmpNioBuf = tmpNioBuf = buffer.duplicate(); 421 } 422 return tmpNioBuf; 423 } 424 425 override 426 ByteBuf copy(int index, int length) { 427 ensureAccessible(); 428 ByteBuffer src; 429 try { 430 src = cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); 431 } catch (IllegalArgumentException ignored) { 432 throw new IndexOutOfBoundsException("Too many bytes to read - Need " ~ to!string(index + length)); 433 } 434 435 ByteBuf dst = src.isDirect() ? alloc().directBuffer(length) : alloc().heapBuffer(length); 436 dst.writeBytes(src); 437 return dst; 438 } 439 440 override 441 int nioBufferCount() { 442 return 1; 443 } 444 445 override 446 ByteBuffer[] nioBuffers(int index, int length) { 447 return [nioBuffer(index, length)]; 448 } 449 450 override 451 ByteBuffer nioBuffer(int index, int length) { 452 checkIndex(index, length); 453 return cast(ByteBuffer) buffer.duplicate().position(index).limit(index + length); 454 } 455 456 override 457 ByteBuffer internalNioBuffer(int index, int length) { 458 ensureAccessible(); 459 return cast(ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length); 460 } 461 462 override 463 bool hasArray() { 464 return buffer.hasArray(); 465 } 466 467 override 468 byte[] array() { 469 return buffer.array(); 470 } 471 472 override 473 int arrayOffset() { 474 return buffer.arrayOffset(); 475 } 476 477 override 478 bool hasMemoryAddress() { 479 return false; 480 } 481 482 override 483 long memoryAddress() { 484 throw new UnsupportedOperationException(); 485 } 486 }