001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.util;
014
015 import java.io.InputStream;
016 import java.io.IOException;
017 import org.vmmagic.unboxed.Address;
018 import org.vmmagic.unboxed.Offset;
019
020 /**
021 * Access raw memory region as an input stream
022 */
023 public final class AddressInputStream extends InputStream {
024 /** Address of memory region to be read */
025 private final Address location;
026 /** Length of the memory region */
027 private final Offset length;
028 /** Offset to be read */
029 private Offset offset;
030 /** Mark offset */
031 private Offset markOffset;
032
033 /** Constructor */
034 public AddressInputStream(Address location, Offset length) {
035 this.location = location;
036 this.length = length;
037 offset = Offset.zero();
038 markOffset = Offset.zero();
039 }
040
041 /** @return number of bytes that can be read */
042 public int available() {
043 return length.minus(offset).toInt();
044 }
045 /** Mark location */
046 public void mark(int readLimit) {
047 markOffset = offset;
048 }
049 /** Is mark/reset supported */
050 public boolean markSupported() {
051 return true;
052 }
053 /** Read a byte */
054 public int read() throws IOException {
055 if (offset.sGE(length)) {
056 throw new IOException("Read beyond end of memory region");
057 }
058 byte result = location.loadByte(offset);
059 offset = offset.plus(1);
060 return result;
061 }
062 /** Reset to mark */
063 public void reset() {
064 offset = markOffset;
065 }
066 /** Skip bytes */
067 public long skip(long n) {
068 offset = offset.plus((int)n);
069 return (long)((int)n);
070 }
071 }