/* JPC: An x86 PC Hardware Emulator for a pure Java Virtual Machine Release Version 2.4 A project from the Physics Dept, The University of Oxford Copyright (C) 2007-2010 The University of Oxford This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program 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 for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Details (including contact information) can be found at: jpc.sourceforge.net or the developer website sourceforge.net/projects/jpc/ Conceived and Developed by: Rhys Newman, Ian Preston, Chris Dennis End of licence header */ package org.jpc.support; import java.io.*; import java.util.logging.*; import static org.jpc.support.RemoteBlockDevice.Protocol; /** * * @author Ian Preston */ public class RemoteBlockDeviceImpl implements Runnable { private static final Logger LOGGING = Logger.getLogger(RemoteBlockDeviceImpl.class.getName()); private DataInputStream in; private DataOutputStream out; private BlockDevice target; private byte[] buffer; public RemoteBlockDeviceImpl(InputStream in, OutputStream out, BlockDevice target) { this.target = target; this.in = new DataInputStream(in); this.out = new DataOutputStream(out); buffer = new byte[1024]; new Thread(this).start(); } public void run() { while (true) { try { int methodType = in.read(); switch (Protocol.values()[methodType]) { case READ: long sectorNumber = in.readLong(); int toRead = Math.min(in.readInt(), buffer.length/512); int result = target.read(sectorNumber, buffer, toRead); out.writeByte(0); out.writeInt(result); out.writeInt(toRead*512); out.write(buffer, 0, toRead*512); break; case WRITE: long writesectorNumber = in.readLong(); int toWrite = Math.min(in.readInt(), buffer.length); in.read(buffer, 0, toWrite); int writeresult = target.write(writesectorNumber, buffer, toWrite); out.writeByte(0); out.writeInt(writeresult); break; case TOTAL_SECTORS: long totalSectors = target.getTotalSectors(); out.writeLong(totalSectors); break; case CYLINDERS: int cylinders = target.getCylinders(); out.writeInt(cylinders); break; case HEADS: int heads = target.getHeads(); out.writeInt(heads); break; case SECTORS: int sectors = target.getSectors(); out.writeInt(sectors); break; case TYPE: int type = target.getType().ordinal(); out.writeInt(type); break; case INSERTED: boolean inserted = target.isInserted(); out.writeBoolean(inserted); break; case LOCKED: boolean locked = target.isLocked(); out.writeBoolean(locked); break; case READ_ONLY: boolean readOnly = target.isReadOnly(); out.writeBoolean(readOnly); break; case SET_LOCKED: boolean setlock = in.readBoolean(); target.setLock(setlock); break; case CLOSE: target.close(); break; default: LOGGING.log(Level.WARNING, "socket closed due to protocol error"); return; } out.flush(); } catch (Exception e) { e.printStackTrace(); System.exit(0); } } } }