protected DirectByteBuffer(MemoryBlock block, int capacity, int offset, boolean isReadOnly, MapMode mapMode) { super(block, capacity, mapMode); long baseSize = block.getSize(); if (baseSize >= 0 && (capacity + offset) > baseSize) { throw new IllegalArgumentException("capacity + offset > baseSize"); } this.effectiveDirectAddress = block.toLong() + offset; this.offset = offset; this.isReadOnly = isReadOnly; }
public static MemoryBlock mmap(FileDescriptor fd, long offset, long size, MapMode mapMode) throws IOException { if (size == 0) { // You can't mmap(2) a zero-length region, but Java allows it. return new MemoryBlock(0, 0); } // Check just those errors mmap(2) won't detect. if (offset < 0 || size < 0 || offset > Integer.MAX_VALUE || size > Integer.MAX_VALUE) { throw new IllegalArgumentException("offset=" + offset + " size=" + size); } int prot; int flags; if (mapMode == MapMode.PRIVATE) { prot = PROT_READ|PROT_WRITE; flags = MAP_PRIVATE; } else if (mapMode == MapMode.READ_ONLY) { prot = PROT_READ; flags = MAP_SHARED; } else { // mapMode == MapMode.READ_WRITE prot = PROT_READ|PROT_WRITE; flags = MAP_SHARED; } try { long address = Libcore.os.mmap(0L, size, prot, flags, fd, offset); return new MemoryMappedBlock(address, size); } catch (ErrnoException errnoException) { throw errnoException.rethrowAsIOException(); } }
/** * Creates a direct byte buffer based on a newly allocated memory block. * * @param capacity * the capacity of the new buffer * @return the created byte buffer. * @throws IllegalArgumentException * if {@code capacity < 0}. */ public static ByteBuffer allocateDirect(int capacity) { if (capacity < 0) { throw new IllegalArgumentException("capacity < 0: " + capacity); } return new DirectByteBuffer(MemoryBlock.allocate(capacity), capacity, 0, false, null); }
@Override public final byte get() { if (position == limit) { throw new BufferUnderflowException(); } return this.block.peekByte(offset + position++); }
@Override boolean protectedHasArray() { return !isReadOnly && (block.array() != null); }
final void get(char[] dst, int dstOffset, int charCount) { int byteCount = checkGetBounds(SizeOf.CHAR, dst.length, dstOffset, charCount); this.block.peekCharArray(offset + position, dst, dstOffset, charCount, order.needsSwap); position += byteCount; }
@Override public final ByteBuffer get(byte[] dst, int dstOffset, int byteCount) { checkGetBounds(1, dst.length, dstOffset, byteCount); this.block.peekByteArray(offset + position, dst, dstOffset, byteCount); position += byteCount; return this; }
public final void free() { block.free(); }
MemoryBlock block = MemoryBlock.mmap(fd, alignment, size + offset, mapMode); return new DirectByteBuffer(block, (int) size, offset, (mapMode == MapMode.READ_ONLY), mapMode);
public static ByteBuffer allocateDirect(int capacity) { if (capacity < 0) { throw new IllegalArgumentException("capacity < 0: " + capacity); } // Ensure alignment by 8. MemoryBlock memoryBlock = MemoryBlock.allocate(capacity + 7); long address = memoryBlock.toLong(); long alignedAddress = (address + 7) & ~(long)7; return new DirectByteBuffer(memoryBlock, capacity, (int)(alignedAddress - address), false, null); }
@Override public final byte get(int index) { checkIndex(index); return this.block.peekByte(offset + index); }
@Override byte[] protectedArray() { if (isReadOnly) { throw new ReadOnlyBufferException(); } byte[] array = this.block.array(); if (array == null) { throw new UnsupportedOperationException(); } return array; }
final void get(char[] dst, int dstOffset, int charCount) { int byteCount = checkGetBounds(SizeOf.CHAR, dst.length, dstOffset, charCount); this.block.peekCharArray(offset + position, dst, dstOffset, charCount, order.needsSwap); position += byteCount; }
@Override public final ByteBuffer get(byte[] dst, int dstOffset, int byteCount) { checkGetBounds(1, dst.length, dstOffset, byteCount); this.block.peekByteArray(offset + position, dst, dstOffset, byteCount); position += byteCount; return this; }
public final void free() { block.free(); }
MemoryBlock block = MemoryBlock.mmap(fd, alignment, size + offset, mapMode); return new DirectByteBuffer(block, (int) size, offset, (mapMode == MapMode.READ_ONLY), mapMode);
/** * Attempts to load every page of this buffer into RAM. See {@link #isLoaded}. * @return this buffer. */ public final MappedByteBuffer load() { checkIsMapped(); try { Libcore.os.mlock(block.toLong(), block.getSize()); Libcore.os.munlock(block.toLong(), block.getSize()); } catch (ErrnoException ignored) { } return this; }
@Override public final byte get() { if (position == limit) { throw new BufferUnderflowException(); } return this.block.peekByte(offset + position++); }
@Override boolean protectedHasArray() { return !isReadOnly && (block.array() != null); }
final void get(char[] dst, int dstOffset, int charCount) { int byteCount = checkGetBounds(SizeOf.CHAR, dst.length, dstOffset, charCount); this.block.peekCharArray(offset + position, dst, dstOffset, charCount, order.needsSwap); position += byteCount; }