⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rio500.java

📁 JAVA 访问USB JAVA 访问USB JAVA 访问USB JAVA 访问USB JAVA 访问USB JAVA 访问USB
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    private static final int	ROOT_FOLDER_ADDRESS = 0xff00;


    /**
     * This class is a base class that wraps a data buffer;
     * subclasses expose the fields in that data.
     */
    static public class Data
    {
	// keep all internals package-private

	final byte	data [];
	final int	off;
	final Rio500	rio;

	Data (Rio500 dev, byte buf []) { rio = dev; data = buf; off = 0; }
	Data (Rio500 dev, byte buf [], int o) { rio = dev; data = buf; off = o; }

	final int getU8 (int index)
	{
	    return data [index] & 0xff;
	}

	final int getU16 (int index)
	{
	    int	retval;

	    index += off;
	    retval  = 0xff & data [index++];
	    retval |= 0xff00 & (data [index] << 8);
	    return retval;
	}

	final int getU32 (int index)
	{
	    int temp;

	    index += off;
			temp  = 0x0ff & data [3 + index];
	    temp <<= 8; temp |= 0x0ff & data [2 + index];
	    temp <<= 8; temp |= 0x0ff & data [1 + index];
	    temp <<= 8; temp |= 0x0ff & data [0 + index];
	    return temp;
	}

	final String getString (int start, int count)
	{
	    try {
		int end;

		start += off;
		for (end = start; count > 0 && data [end] != 0; end++)
		    count--;
			    // NOTE:  this constructor doesn't exist
			    // in some embedded profiles
		return new String (data, start, end - start, "8859_1");
	    } catch (UnsupportedEncodingException e) {
		throw new RuntimeException ("8859_1");	// "can't happen"
	    }
	}
    }

    /** Exposes the fields of a memory status record.  */
    final static public class MemoryStatus extends Data
    {
	MemoryStatus (Rio500 dev, byte buf []) { super (dev, buf); }

	// 2 bytes ?
	public int getBlockSize () { return getU16 (2); }
	public int getBlockCount () { return getU16 (4); }
	public int getFirstFreeBlock () { return getU16 (6); }
	public int getNumUnusedBlocks () { return getU16 (8); }
	// 4 bytes ?
	// 4 bytes ?
    }

    /** Exposes the fields desribing a folder. */
    final static public class FolderEntry extends Data
    {
	private boolean	external;
	private int	folderNumber;

	FolderEntry (Rio500 dev, boolean e, int folder, Data d, int off)
	{
	    super (dev, d.data, d.off + off);
	    external = e;
	    folderNumber = folder;
	}
	
	public int getFolderNumber () { return folderNumber; }
	
	public int getOffset () { return getU16 (0); }
	// 2 bytes ? /2
	public int getFirstFreeEntryOffset () { return getU16 (4); }
	// 2 bytes ? /6
	// 4 bytes ? /8
	// 4 bytes ? /12
	public int getTime () { return getU16 (16); }
	// Bitmap /20
	public String getName1 () { return getString (1558, 362); }
	public String getName2 () { return getString (1920, 128); }


	// song entries are eight per block (like folders)

	public int getSongCount ()
	    { return getFirstFreeEntryOffset () / SONG_ENTRY_SIZE; }
	
	public SongEntry [] getSongs ()
	throws IOException
	{
	    int		temp = getFirstFreeEntryOffset ();

	    // a lot of these calculations feel quite odd
	    // they're from the c code

	    int		blocks = temp / BLOCKSIZE;
	    int		count = 8 * blocks;

	    temp %= BLOCKSIZE;
	    if (temp > 0)
		blocks++;
	    count += temp / SONG_ENTRY_SIZE;

	    byte 	data [] = new byte [blocks * BLOCKSIZE];
	    SongEntry	retval [] = new SongEntry [count];

	    int		address = getFolderNumber ();

	    address <<= 8;
	    address |= 0x0ff;
	    address &= 0xfff;
	    rio.read (external, address, data, 0, data.length);

	    address = 0;
	    for (int i = 0; i < retval.length; i++) {
		retval [i] = new SongEntry (this, data, address);
		address += SONG_ENTRY_SIZE;
	    }

	    return retval;
	}

	/** Returns true if the folder is on a removable memory card */
	public boolean isExternal () { return external; }

	// upload song
	// download song
	// delete song
	// rename song
    }

    /**
     * Represents the information known about each song.
     */
    static final public class SongEntry extends Data
    {
	private FolderEntry	folder;

	SongEntry (FolderEntry f, byte buf [], int off)
	    { super (f.rio, buf, off); folder = f; }

	public int getOffset () { return getU16 (0); }
	// 2 bytes ?/2
	public int getLength () { return getU32 (4); }
	// 2 bytes ?/8
	// 2 bytes ?/10
	public int getMP3Sig () { return getU32 (12); }
	public int getTime () { return getU32 (16); }
	// Bitmap/20
	public String getName1 () { return getString (1558, 362); }
	public String getName2 () { return getString (1920, 128); }

	// for debug
	public void dump ()
	{
	}

	FolderEntry	getFolder () { return folder; }

	// long		getSize () { return 0; }
	// int		getNumber () { return 0; }
    }

/*
    static final class Bitmap extends Data
    {
	// 2 bytes == #blocks
	// 1536 bytes == bits
    }

    static final public class FolderLocation extends Data
    {
	// 2 bytes offset
	// 2 bytes bytes
	// 2 bytes folder num
    }

    // FOLDER OPS:
	// add folder
	// rename folder
	// delete folder
	// [get folder location]
    
    // format
    // set report func
    // destroy content
    // get content

    // font operations
*/

    /*==================================================================*/
    
    // read and write chunks of memory starting at a given block

    private void read (boolean external, int address, byte buf [], int off, int len)
    throws IOException
    {
	int val;
	int card = external ? 1 : 0;

	if ((len % BLOCKSIZE) != 0)
	    throw new IllegalArgumentException ();

	if ((val = get (RIO_SET_READ_PTR, address, card)) == 0
		|| (val = get (RIO_SET_READ_LEN,
				len / IO_SIZE_BIG,
				len % IO_SIZE_BIG)) == 0)
	    throw new IOException ("rio read");
	// value of the READ command appears to be bytecount (len).
	socket.getInputStream ().read (buf, off, len);
    }

    private void write (int address, byte buf [], int off, int len)
    throws IOException
    {
	int val;

	if ((len % BLOCKSIZE) != 0)
	    throw new IllegalArgumentException ();
	if ((val = get (RIO_UNKNOWN_4C, address, 0)) == 0
		|| (val = get (RIO_UNKNOWN_4F, address, 0)) == 0
		|| (val = get (RIO_WRITE,
				len / IO_SIZE_BIG,
				len % IO_SIZE_BIG)) == 0)
	    throw new IOException ("rio write");
	socket.getOutputStream ().write (buf, off, len);
    }

    /*==================================================================*/

    // sends 32 bits with request code; receives 32 bits back
    // 0 indicates failure
    private int get (byte req, int value, int index)
    throws IOException
    {
	synchronized (msg) {
	    return new Data (this, rioRead (req, value, index, 4)).getU32 (0);
	}
    }

    // synchronize on 'msg' before calling this

    private byte [] rioRead (byte req, int value, int index, int length)
    throws IOException
    {
	msg.setRequestType ((byte) (ControlMessage.DIR_TO_HOST
		    | ControlMessage.RECIPIENT_DEVICE
		    | ControlMessage.TYPE_VENDOR));
	msg.setRequest (req);
	msg.setValue ((short)value);
	msg.setIndex ((short)index);
	msg.setLength (length);

	socket.getDevice ().control (msg);
	return msg.getBuffer ();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -