/* * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.max.tele.data; import java.nio.*; import com.sun.max.unsafe.*; /** * Buffered reading/writing of bytes from/to a source/destination that can be identified by an {@link Address}. */ public interface DataIO { /** * Reads bytes from an address into a given byte buffer. * * Precondition: * {@code buffer != null && offset >= 0 && offset < buffer.capacity() && length >= 0 && offset + length <= buffer.capacity()} * * @param src the address from which reading should start * @param dst the buffer into which the bytes are read * @param dstOffset the offset in {@code dst} at which the bytes are read * @param length the maximum number of bytes to be read * @return the number of bytes read into {@code dst} * * @throws DataIOError if some IO error occurs * @throws IndexOutOfBoundsException if {@code offset} is negative, {@code length} is negative, or * {@code length > buffer.limit() - offset} */ int read(Address src, ByteBuffer dst, int dstOffset, int length) throws DataIOError, IndexOutOfBoundsException; /** * Writes bytes from a given byte buffer to a given address. * * Precondition: * {@code buffer != null && offset >= 0 && offset < buffer.capacity() && length >= 0 && offset + length <= buffer.capacity()} * * @param src the buffer from which the bytes are written * @param srcOffset the offset in {@code src} from which the bytes are written * @param length the maximum number of bytes to be written * @param dst the address at which writing should start * @return the number of bytes written to {@code dst} * * @throws DataIOError if some IO error occurs * @throws IndexOutOfBoundsException if {@code srcOffset} is negative, {@code length} is negative, or * {@code length > src.limit() - srcOffset} */ int write(ByteBuffer src, int srcOffset, int length, Address dst) throws DataIOError, IndexOutOfBoundsException; public static class Static { /** * Fills a buffer by reading bytes from a source. * * @param dataIO the source of data to be read * @param src the location in the source where reading should start * @param dst the buffer to be filled with the data * @throws DataIOError if the read fails */ public static void readFully(DataIO dataIO, Address src, ByteBuffer dst) throws DataIOError { final int length = dst.limit(); int n = 0; assert dst.position() == 0; while (n < length) { final int count = dataIO.read(src.plus(n), dst, n, length - n); if (count <= 0) { throw new DataIOError(src, (length - n) + " of " + length + " bytes unread"); } n += count; dst.position(0); } } /** * Reads bytes from a source. * * @param dataIO the source of data to be read * @param src the location in the source where reading should start * @param length the total number of bytes to be read * @return the bytes read from the source. * @throws DataIOError if the read fails */ public static byte[] readFully(DataIO dataIO, Address src, int length) throws DataIOError { final ByteBuffer buffer = ByteBuffer.wrap(new byte[length]); readFully(dataIO, src, buffer); return buffer.array(); } /** * Checks the preconditions related to the destination buffer for {@link DataIO#read(Address, ByteBuffer, int, int)}. */ public static void checkRead(ByteBuffer dst, int dstOffset, int length) { if (dst == null) { throw new NullPointerException(); } else if (dstOffset < 0 || length < 0 || length > dst.limit() - dstOffset) { throw new IndexOutOfBoundsException(); } } /** * Checks the preconditions related to the source buffer for {@link DataIO#write(ByteBuffer, int, int, Address)}. */ public static void checkWrite(ByteBuffer src, int srcOffset, int length) { if ((srcOffset < 0) || (srcOffset > src.limit()) || (length < 0) || ((srcOffset + length) > src.limit()) || ((srcOffset + length) < 0)) { throw new IndexOutOfBoundsException(); } } } }