// Path: src/usb/util/USBSocket.java
// public final class USBSocket
// {
//     private Interface		intf;
//     private InputStream		in;
//     private OutputStream	out;
// 
//     /**
//      * Initializes the socket using a bulk-only device.
//      *
//      * @exception IOException if the interface is already claimed by
//      *	another driver module; or if the configuration, interface, or
//      *	endpoints can't be accessed; and for other reasons.
//      * @exception IllegalArgumentException if the interface doesn't
//      *	have exactly two endpoints, for bulk input and bulk output.
//      */
//     public USBSocket (Device dev)
//     throws IOException
//     {
// 	DeviceDescriptor	info = dev.getDeviceDescriptor ();
// 
// 	if (info.getNumConfigurations () != 1
// 		|| dev.getConfiguration ().getNumInterfaces () != 1
// 		// or that interface has alternates
// 		)
// 	    throw new IllegalArgumentException ();
// 	init (dev.getConfiguration ().getInterface (0, 0));
//     }
// 
//     /**
//      * Initializes the socket using a bulk-only interface on a
//      * device which may have additional interfaces.
//      *
//      * @exception IOException if the interface is already claimed by
//      *	another driver module, or if the endpoints can't be accessed.
//      * @exception IllegalArgumentException if the interface doesn't
//      *	have exactly two endpoints, for bulk input and bulk output.
//      */
//     public USBSocket (Interface intf)
//     throws IOException
//     {
// 	init (intf);
//     }
// 
//     private void init (Interface intf)
//     throws IOException
//     {
// 	if (intf == null || intf.getNumEndpoints () != 2)
// 	    throw new IllegalArgumentException ();
// 
// 	// XXX presumably this handles the "multiple devfs claims" case; check.
// 
// 	intf.claim ();
// 	this.intf = intf;
// 
// 	try {
// 	    for (int i = 0; i < intf.getNumEndpoints (); i++) {
// 		Endpoint	ep = intf.getEndpoint (i);
// 		
// 		if (!"bulk".equals (ep.getType ()))
// 		    throw new IllegalArgumentException ();
// 		if (ep.isInput ())
// 		    in = ep.getInputStream ();
// 		else
// 		    out = ep.getOutputStream ();
// 	    }
// 	    if (in == null || out == null)
// 		throw new IllegalArgumentException ();
// 	} catch (IOException e) {
// 	    try { close (); } catch (Exception x) { intf = null; } 
// 	    throw e;
// 	} catch (RuntimeException e) {
// 	    try { close (); } catch (Exception x) { intf = null; } 
// 	    throw e;
// 	}
//     }
// 
//     /**
//      * Releases the interface, so that some other software driver can
//      * use it to access this device.  Both directions of the socket
//      * are closed down.  The behavior seen by other threads trying
//      * to send or receive data is undefined.
//      */
//     public void close () throws IOException
//     {
// 	in = null;
// 	out = null;
// 	if (intf != null)
// 	    intf.release ();
// 	intf = null;
//     }
// 
//     /**
//      * Finalization releases the interface, if it has not already been
//      * released by invoking close().
//      */
//     protected void finalize () throws IOException
//     {
// 	close ();
//     }
// 
//     /**
//      * Returns an input stream used to perform bulk reads from the interface, or null.
//      */
//     public InputStream getInputStream () { return in; }
// 
//     /**
//      * Returns an output stream used to perform bulk writes to the interface, or null.
//      */
//     public OutputStream getOutputStream () { return out; }
// 
//     /**
//      * Returns the device to which this socket is connected, or null if the
//      * device has been closed or removed.
//      */
//     public Device getDevice () { return (intf != null) ? intf.getDevice () : null; }
// }


import usb.core.*;
import usb.util.USBSocket;
import java.io.*;
import java.util.Vector;

    /**
     * Returns true if a removable SmartMedia memory card is available
     * for song storage.
     */
    public boolean hasExternalMemory () throws IOException
    {
	return ((get (RIO_UNKNOWN_42, 0, 0) >> 30) & 0x01) != 0;
    }

    /**
     * Returns information about the internal or external memory.
     * @param external when true, the external memory is checked.
     */
    public MemoryStatus getMemoryStatus (boolean external) throws IOException
    {
	checkTalking ();
	synchronized (msg) {
	    // which card provides the status?
	    get (RIO_UNKNOWN_51, 1, external ? 1 : 0);

	    return new MemoryStatus (this, rioRead (RIO_MEM_STATUS, 0, 0, 20));
	}
    }


    private int getFolderBlockCount (boolean external)
    throws IOException
    {
	int card = external ? 1 : 0;
// Path: src/usb/util/USBSocket.java
// public final class USBSocket
// {
//     private Interface		intf;
//     private InputStream		in;
//     private OutputStream	out;
// 
//     /**
//      * Initializes the socket using a bulk-only device.
//      *
//      * @exception IOException if the interface is already claimed by
//      *	another driver module; or if the configuration, interface, or
//      *	endpoints can't be accessed; and for other reasons.
//      * @exception IllegalArgumentException if the interface doesn't
//      *	have exactly two endpoints, for bulk input and bulk output.
//      */
//     public USBSocket (Device dev)
//     throws IOException
//     {
// 	DeviceDescriptor	info = dev.getDeviceDescriptor ();
// 
// 	if (info.getNumConfigurations () != 1
// 		|| dev.getConfiguration ().getNumInterfaces () != 1
// 		// or that interface has alternates
// 		)
// 	    throw new IllegalArgumentException ();
// 	init (dev.getConfiguration ().getInterface (0, 0));
//     }
// 
//     /**
//      * Initializes the socket using a bulk-only interface on a
//      * device which may have additional interfaces.
//      *
//      * @exception IOException if the interface is already claimed by
//      *	another driver module, or if the endpoints can't be accessed.
//      * @exception IllegalArgumentException if the interface doesn't
//      *	have exactly two endpoints, for bulk input and bulk output.
//      */
//     public USBSocket (Interface intf)
//     throws IOException
//     {
// 	init (intf);
//     }
// 
//     private void init (Interface intf)
//     throws IOException
//     {
// 	if (intf == null || intf.getNumEndpoints () != 2)
// 	    throw new IllegalArgumentException ();
// 
// 	// XXX presumably this handles the "multiple devfs claims" case; check.
// 
// 	intf.claim ();
// 	this.intf = intf;
// 
// 	try {
// 	    for (int i = 0; i < intf.getNumEndpoints (); i++) {
// 		Endpoint	ep = intf.getEndpoint (i);
// 		
// 		if (!"bulk".equals (ep.getType ()))
// 		    throw new IllegalArgumentException ();
// 		if (ep.isInput ())
// 		    in = ep.getInputStream ();
// 		else
// 		    out = ep.getOutputStream ();
// 	    }
// 	    if (in == null || out == null)
// 		throw new IllegalArgumentException ();
// 	} catch (IOException e) {
// 	    try { close (); } catch (Exception x) { intf = null; } 
// 	    throw e;
// 	} catch (RuntimeException e) {
// 	    try { close (); } catch (Exception x) { intf = null; } 
// 	    throw e;
// 	}
//     }
// 
//     /**
//      * Releases the interface, so that some other software driver can
//      * use it to access this device.  Both directions of the socket
//      * are closed down.  The behavior seen by other threads trying
//      * to send or receive data is undefined.
//      */
//     public void close () throws IOException
//     {
// 	in = null;
// 	out = null;
// 	if (intf != null)
// 	    intf.release ();
// 	intf = null;
//     }
// 
//     /**
//      * Finalization releases the interface, if it has not already been
//      * released by invoking close().
//      */
//     protected void finalize () throws IOException
//     {
// 	close ();
//     }
// 
//     /**
//      * Returns an input stream used to perform bulk reads from the interface, or null.
//      */
//     public InputStream getInputStream () { return in; }
// 
//     /**
//      * Returns an output stream used to perform bulk writes to the interface, or null.
//      */
//     public OutputStream getOutputStream () { return out; }
// 
//     /**
//      * Returns the device to which this socket is connected, or null if the
//      * device has been closed or removed.
//      */
//     public Device getDevice () { return (intf != null) ? intf.getDevice () : null; }
// }


// Path: src/usb/devices/Rio500.java
import usb.core.*;
import usb.util.USBSocket;
import java.io.*;
import java.util.Vector;


    /**
     * Returns true if a removable SmartMedia memory card is available
     * for song storage.
     */
    public boolean hasExternalMemory () throws IOException
    {
	return ((get (RIO_UNKNOWN_42, 0, 0) >> 30) & 0x01) != 0;
    }

    /**
     * Returns information about the internal or external memory.
     * @param external when true, the external memory is checked.
     */
    public MemoryStatus getMemoryStatus (boolean external) throws IOException
    {
	checkTalking ();
	synchronized (msg) {
	    // which card provides the status?
	    get (RIO_UNKNOWN_51, 1, external ? 1 : 0);

	    return new MemoryStatus (this, rioRead (RIO_MEM_STATUS, 0, 0, 20));
	}
    }


    private int getFolderBlockCount (boolean external)
    throws IOException
    {
	int card = external ? 1 : 0;
	return get (RIO_GET_BLOCK_COUNT, ROOT_FOLDER_ADDRESS, card);