1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.buffer;
17
18 import io.netty.util.internal.StringUtil;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25 import java.nio.ReadOnlyBufferException;
26 import java.nio.channels.FileChannel;
27 import java.nio.channels.GatheringByteChannel;
28 import java.nio.channels.ScatteringByteChannel;
29
30
31
32
33
34 class ReadOnlyByteBufferBuf extends AbstractReferenceCountedByteBuf {
35
36 protected final ByteBuffer buffer;
37 private final ByteBufAllocator allocator;
38 private ByteBuffer tmpNioBuf;
39
40 ReadOnlyByteBufferBuf(ByteBufAllocator allocator, ByteBuffer buffer) {
41 super(buffer.remaining());
42 if (!buffer.isReadOnly()) {
43 throw new IllegalArgumentException("must be a readonly buffer: " + StringUtil.simpleClassName(buffer));
44 }
45
46 this.allocator = allocator;
47 this.buffer = buffer.slice().order(ByteOrder.BIG_ENDIAN);
48 writerIndex(this.buffer.limit());
49 }
50
51 @Override
52 protected void deallocate() { }
53
54 @Override
55 public boolean isWritable() {
56 return false;
57 }
58
59 @Override
60 public boolean isWritable(int numBytes) {
61 return false;
62 }
63
64 @Override
65 public ByteBuf ensureWritable(int minWritableBytes) {
66 throw new ReadOnlyBufferException();
67 }
68
69 @Override
70 public int ensureWritable(int minWritableBytes, boolean force) {
71 return 1;
72 }
73
74 @Override
75 public byte getByte(int index) {
76 ensureAccessible();
77 return _getByte(index);
78 }
79
80 @Override
81 protected byte _getByte(int index) {
82 return buffer.get(index);
83 }
84
85 @Override
86 public short getShort(int index) {
87 ensureAccessible();
88 return _getShort(index);
89 }
90
91 @Override
92 protected short _getShort(int index) {
93 return buffer.getShort(index);
94 }
95
96 @Override
97 public short getShortLE(int index) {
98 ensureAccessible();
99 return _getShortLE(index);
100 }
101
102 @Override
103 protected short _getShortLE(int index) {
104 return ByteBufUtil.swapShort(buffer.getShort(index));
105 }
106
107 @Override
108 public int getUnsignedMedium(int index) {
109 ensureAccessible();
110 return _getUnsignedMedium(index);
111 }
112
113 @Override
114 protected int _getUnsignedMedium(int index) {
115 return (getByte(index) & 0xff) << 16 |
116 (getByte(index + 1) & 0xff) << 8 |
117 getByte(index + 2) & 0xff;
118 }
119
120 @Override
121 public int getUnsignedMediumLE(int index) {
122 ensureAccessible();
123 return _getUnsignedMediumLE(index);
124 }
125
126 @Override
127 protected int _getUnsignedMediumLE(int index) {
128 return getByte(index) & 0xff |
129 (getByte(index + 1) & 0xff) << 8 |
130 (getByte(index + 2) & 0xff) << 16;
131 }
132
133 @Override
134 public int getInt(int index) {
135 ensureAccessible();
136 return _getInt(index);
137 }
138
139 @Override
140 protected int _getInt(int index) {
141 return buffer.getInt(index);
142 }
143
144 @Override
145 public int getIntLE(int index) {
146 ensureAccessible();
147 return _getIntLE(index);
148 }
149
150 @Override
151 protected int _getIntLE(int index) {
152 return ByteBufUtil.swapInt(buffer.getInt(index));
153 }
154
155 @Override
156 public long getLong(int index) {
157 ensureAccessible();
158 return _getLong(index);
159 }
160
161 @Override
162 protected long _getLong(int index) {
163 return buffer.getLong(index);
164 }
165
166 @Override
167 public long getLongLE(int index) {
168 ensureAccessible();
169 return _getLongLE(index);
170 }
171
172 @Override
173 protected long _getLongLE(int index) {
174 return ByteBufUtil.swapLong(buffer.getLong(index));
175 }
176
177 @Override
178 public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
179 return getBytes(index, dst, dstIndex, length, false);
180 }
181
182 @Override
183 public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
184 checkReadableBytes(length);
185 getBytes(readerIndex, dst, dstIndex, length, true);
186 readerIndex += length;
187 return this;
188 }
189
190 protected ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length, boolean internal) {
191 checkDstIndex(index, length, dstIndex, dst.capacity());
192 if (dst.hasArray()) {
193 getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
194 } else if (dst.nioBufferCount() > 0) {
195 for (ByteBuffer bb: dst.nioBuffers(dstIndex, length)) {
196 int bbLen = bb.remaining();
197 getBytes(index, bb, internal);
198 index += bbLen;
199 }
200 } else {
201 dst.setBytes(dstIndex, this, index, length);
202 }
203 return this;
204 }
205
206 @Override
207 public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
208 return getBytes(index, dst, dstIndex, length, false);
209 }
210
211 @Override
212 public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
213 checkReadableBytes(length);
214 getBytes(readerIndex, dst, dstIndex, length, true);
215 readerIndex += length;
216 return this;
217 }
218
219 protected ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length, boolean internal) {
220 checkDstIndex(index, length, dstIndex, dst.length);
221
222 final ByteBuffer tmpBuf = nioBuffer(internal);
223 tmpBuf.clear().position(index).limit(index + length);
224 tmpBuf.get(dst, dstIndex, length);
225 return this;
226 }
227
228 @Override
229 public ByteBuf getBytes(int index, ByteBuffer dst) {
230 return getBytes(index, dst, false);
231 }
232
233 @Override
234 public ByteBuf readBytes(ByteBuffer dst) {
235 int length = dst.remaining();
236 checkReadableBytes(length);
237 getBytes(readerIndex, dst, true);
238 readerIndex += length;
239 return this;
240 }
241
242 private ByteBuf getBytes(int index, ByteBuffer dst, boolean internal) {
243 checkIndex(index, dst.remaining());
244
245 final ByteBuffer tmpBuf = nioBuffer(internal);
246 tmpBuf.clear().position(index).limit(index + dst.remaining());
247 dst.put(tmpBuf);
248 return this;
249 }
250
251 @Override
252 public ByteBuf setByte(int index, int value) {
253 throw new ReadOnlyBufferException();
254 }
255
256 @Override
257 protected void _setByte(int index, int value) {
258 throw new ReadOnlyBufferException();
259 }
260
261 @Override
262 public ByteBuf setShort(int index, int value) {
263 throw new ReadOnlyBufferException();
264 }
265
266 @Override
267 protected void _setShort(int index, int value) {
268 throw new ReadOnlyBufferException();
269 }
270
271 @Override
272 public ByteBuf setShortLE(int index, int value) {
273 throw new ReadOnlyBufferException();
274 }
275
276 @Override
277 protected void _setShortLE(int index, int value) {
278 throw new ReadOnlyBufferException();
279 }
280
281 @Override
282 public ByteBuf setMedium(int index, int value) {
283 throw new ReadOnlyBufferException();
284 }
285
286 @Override
287 protected void _setMedium(int index, int value) {
288 throw new ReadOnlyBufferException();
289 }
290
291 @Override
292 public ByteBuf setMediumLE(int index, int value) {
293 throw new ReadOnlyBufferException();
294 }
295
296 @Override
297 protected void _setMediumLE(int index, int value) {
298 throw new ReadOnlyBufferException();
299 }
300
301 @Override
302 public ByteBuf setInt(int index, int value) {
303 throw new ReadOnlyBufferException();
304 }
305
306 @Override
307 protected void _setInt(int index, int value) {
308 throw new ReadOnlyBufferException();
309 }
310
311 @Override
312 public ByteBuf setIntLE(int index, int value) {
313 throw new ReadOnlyBufferException();
314 }
315
316 @Override
317 protected void _setIntLE(int index, int value) {
318 throw new ReadOnlyBufferException();
319 }
320
321 @Override
322 public ByteBuf setLong(int index, long value) {
323 throw new ReadOnlyBufferException();
324 }
325
326 @Override
327 protected void _setLong(int index, long value) {
328 throw new ReadOnlyBufferException();
329 }
330
331 @Override
332 public ByteBuf setLongLE(int index, long value) {
333 throw new ReadOnlyBufferException();
334 }
335
336 @Override
337 protected void _setLongLE(int index, long value) {
338 throw new ReadOnlyBufferException();
339 }
340
341 @Override
342 public int capacity() {
343 return maxCapacity();
344 }
345
346 @Override
347 public ByteBuf capacity(int newCapacity) {
348 throw new ReadOnlyBufferException();
349 }
350
351 @Override
352 public ByteBufAllocator alloc() {
353 return allocator;
354 }
355
356 @Override
357 public ByteOrder order() {
358 return ByteOrder.BIG_ENDIAN;
359 }
360
361 @Override
362 public ByteBuf unwrap() {
363 return null;
364 }
365
366 @Override
367 public boolean isReadOnly() {
368 return buffer.isReadOnly();
369 }
370
371 @Override
372 public boolean isDirect() {
373 return buffer.isDirect();
374 }
375
376 @Override
377 public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
378 return getBytes(index, out, length, false);
379 }
380
381 @Override
382 public ByteBuf readBytes(OutputStream out, int length) throws IOException {
383 checkReadableBytes(length);
384 getBytes(readerIndex, out, length, true);
385 readerIndex += length;
386 return this;
387 }
388
389 private ByteBuf getBytes(int index, OutputStream out, int length, boolean internal) throws IOException {
390 ensureAccessible();
391 if (length == 0) {
392 return this;
393 }
394
395 if (buffer.hasArray()) {
396 out.write(buffer.array(), index + buffer.arrayOffset(), length);
397 } else {
398 byte[] tmp = ByteBufUtil.threadLocalTempArray(length);
399 ByteBuffer tmpBuf = nioBuffer(internal);
400 tmpBuf.clear().position(index);
401 tmpBuf.get(tmp, 0, length);
402 out.write(tmp, 0, length);
403 }
404 return this;
405 }
406
407 @Override
408 public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
409 return getBytes(index, out, length, false);
410 }
411
412 @Override
413 public int readBytes(GatheringByteChannel out, int length) throws IOException {
414 checkReadableBytes(length);
415 int readBytes = getBytes(readerIndex, out, length, true);
416 readerIndex += readBytes;
417 return readBytes;
418 }
419
420 private int getBytes(int index, GatheringByteChannel out, int length, boolean internal) throws IOException {
421 ensureAccessible();
422 if (length == 0) {
423 return 0;
424 }
425
426 ByteBuffer tmpBuf = nioBuffer(internal);
427 tmpBuf.clear().position(index).limit(index + length);
428 return out.write(tmpBuf);
429 }
430
431 @Override
432 public int getBytes(int index, FileChannel out, long position, int length) throws IOException {
433 return getBytes(index, out, position, length, false);
434 }
435
436 @Override
437 public int readBytes(FileChannel out, long position, int length) throws IOException {
438 checkReadableBytes(length);
439 int readBytes = getBytes(readerIndex, out, position, length, true);
440 readerIndex += readBytes;
441 return readBytes;
442 }
443
444 private int getBytes(int index, FileChannel out, long position, int length, boolean internal) throws IOException {
445 ensureAccessible();
446 if (length == 0) {
447 return 0;
448 }
449
450 ByteBuffer tmpBuf = nioBuffer(internal);
451 tmpBuf.clear().position(index).limit(index + length);
452 return out.write(tmpBuf, position);
453 }
454
455 @Override
456 public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
457 throw new ReadOnlyBufferException();
458 }
459
460 @Override
461 public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
462 throw new ReadOnlyBufferException();
463 }
464
465 @Override
466 public ByteBuf setBytes(int index, ByteBuffer src) {
467 throw new ReadOnlyBufferException();
468 }
469
470 @Override
471 public int setBytes(int index, InputStream in, int length) throws IOException {
472 throw new ReadOnlyBufferException();
473 }
474
475 @Override
476 public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
477 throw new ReadOnlyBufferException();
478 }
479
480 @Override
481 public int setBytes(int index, FileChannel in, long position, int length) throws IOException {
482 throw new ReadOnlyBufferException();
483 }
484
485 protected final ByteBuffer internalNioBuffer() {
486 ByteBuffer tmpNioBuf = this.tmpNioBuf;
487 if (tmpNioBuf == null) {
488 this.tmpNioBuf = tmpNioBuf = buffer.duplicate();
489 }
490 return tmpNioBuf;
491 }
492
493 @Override
494 public ByteBuf copy(int index, int length) {
495 ensureAccessible();
496 ByteBuffer src;
497 try {
498
499 src = (ByteBuffer) buffer.duplicate().clear().position(index).limit(index + length);
500 } catch (IllegalArgumentException ignored) {
501 throw new IndexOutOfBoundsException("Too many bytes to read - Need " + (index + length));
502 }
503
504 ByteBuf dst = src.isDirect() ? alloc().directBuffer(length) : alloc().heapBuffer(length);
505 dst.writeBytes(src);
506 return dst;
507 }
508
509 @Override
510 public int nioBufferCount() {
511 return 1;
512 }
513
514 @Override
515 public ByteBuffer[] nioBuffers(int index, int length) {
516 return new ByteBuffer[] { nioBuffer(index, length) };
517 }
518
519 @Override
520 public ByteBuffer nioBuffer(int index, int length) {
521 checkIndex(index, length);
522 return (ByteBuffer) buffer.duplicate().position(index).limit(index + length);
523 }
524
525 @Override
526 public ByteBuffer internalNioBuffer(int index, int length) {
527 ensureAccessible();
528 return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
529 }
530
531 @Override
532 public final boolean isContiguous() {
533 return true;
534 }
535
536 @Override
537 public boolean hasArray() {
538 return buffer.hasArray();
539 }
540
541 @Override
542 public byte[] array() {
543 return buffer.array();
544 }
545
546 @Override
547 public int arrayOffset() {
548 return buffer.arrayOffset();
549 }
550
551 @Override
552 public boolean hasMemoryAddress() {
553 return false;
554 }
555
556 @Override
557 public long memoryAddress() {
558 throw new UnsupportedOperationException();
559 }
560
561 private ByteBuffer nioBuffer(boolean internal) {
562 return internal ? internalNioBuffer() : buffer.duplicate();
563 }
564
565 @Override
566 public ByteBuf duplicate() {
567 return new ReadOnlyDuplicatedByteBuf(this);
568 }
569
570 @Override
571 public ByteBuf slice(int index, int length) {
572 return new ReadOnlySlicedByteBuf(this, index, length);
573 }
574
575 @Override
576 public ByteBuf asReadOnly() {
577 return this;
578 }
579
580 @SuppressWarnings("deprecation")
581 private static final class ReadOnlySlicedByteBuf extends SlicedByteBuf {
582 ReadOnlySlicedByteBuf(ByteBuf buffer, int index, int length) {
583 super(buffer, index, length);
584 }
585
586 @Override
587 public ByteBuf asReadOnly() {
588 return this;
589 }
590
591 @Override
592 public ByteBuf slice(int index, int length) {
593 return new ReadOnlySlicedByteBuf(this, index, length);
594 }
595
596 @Override
597 public ByteBuf duplicate() {
598 return slice(0, capacity()).setIndex(readerIndex(), writerIndex());
599 }
600
601 @Override
602 public boolean isWritable() {
603 return false;
604 }
605
606 @Override
607 public boolean isWritable(int numBytes) {
608 return false;
609 }
610
611 @Override
612 public int ensureWritable(int minWritableBytes, boolean force) {
613 return 1;
614 }
615 }
616
617 @SuppressWarnings("deprecation")
618 private static final class ReadOnlyDuplicatedByteBuf extends DuplicatedByteBuf {
619 ReadOnlyDuplicatedByteBuf(ByteBuf buffer) {
620 super(buffer);
621 }
622
623 @Override
624 public ByteBuf asReadOnly() {
625 return this;
626 }
627
628 @Override
629 public ByteBuf slice(int index, int length) {
630 return new ReadOnlySlicedByteBuf(this, index, length);
631 }
632
633 @Override
634 public ByteBuf duplicate() {
635 return new ReadOnlyDuplicatedByteBuf(this);
636 }
637
638 @Override
639 public boolean isWritable() {
640 return false;
641 }
642
643 @Override
644 public boolean isWritable(int numBytes) {
645 return false;
646 }
647
648 @Override
649 public int ensureWritable(int minWritableBytes, boolean force) {
650 return 1;
651 }
652 }
653 }