/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.util; import java.io.InputStream; import java.io.IOException; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; /** * Access raw memory region as an input stream */ public final class AddressInputStream extends InputStream { /** Address of memory region to be read */ private final Address location; /** Length of the memory region */ private final Offset length; /** Offset to be read */ private Offset offset; /** Mark offset */ private Offset markOffset; /** Constructor */ public AddressInputStream(Address location, Offset length) { this.location = location; this.length = length; offset = Offset.zero(); markOffset = Offset.zero(); } /** @return number of bytes that can be read */ public int available() { return length.minus(offset).toInt(); } /** Mark location */ public void mark(int readLimit) { markOffset = offset; } /** Is mark/reset supported */ public boolean markSupported() { return true; } /** Read a byte */ public int read() throws IOException { if (offset.sGE(length)) { throw new IOException("Read beyond end of memory region"); } byte result = location.loadByte(offset); offset = offset.plus(1); return result; } /** Reset to mark */ public void reset() { offset = markOffset; } /** Skip bytes */ public long skip(long n) { offset = offset.plus((int)n); return (long)((int)n); } }