FileDocCategorySizeDatePackage
ResourceInputStream.javaAPI DocJ2ME CLDC 1.15093Wed Feb 05 15:55:58 GMT 2003com.sun.cldc.io

ResourceInputStream

public class ResourceInputStream extends InputStream

Fields Summary
private Object
handle
private int
pos
private int
size
Constructors Summary
public ResourceInputStream(String name)
Construct a resource input stream for accessing objects in the jar file.

param
name the name of the resource in classpath to access. The name must not have a leading '/'.
exception
IOException if an I/O error occurs.

        String fixedName = fixResourceName(name);

        handle = open(fixedName);
        if (handle == null) {
            throw new IOException();
        }
        size = size(handle);
        pos = 0;
    
Methods Summary
public intavailable()

        return size - pos;
    
public synchronized voidclose()

        close(handle);
        handle = null;
    
private static native voidclose(java.lang.Object handle)

private static java.lang.StringfixResourceName(java.lang.String name)
Fixes the resource name to be conformant with the CLDC 1.0 specification. We are not allowed to use "../" to get outside of the .jar file.

param
name the name of the resource in classpath to access.
return
the fixed string.
exception
IOException if the resource name points to a classfile, as determined by the resource name's extension.

        Vector dirVector = new Vector();
        int    startIdx = 0;
        int    endIdx = 0;
        String curDir;

        while ((endIdx = name.indexOf('/", startIdx)) != -1) {
            if (endIdx == startIdx) {
                // We have a leading '/' or two consecutive '/'s
                startIdx++;
                continue;
            }

            curDir = name.substring(startIdx, endIdx);
            startIdx = endIdx + 1;

            if (curDir.equals(".")) {
                // Ignore a single '.' directory
                continue;
            }
            if (curDir.equals("..")) {
                // Go up a level
                try {
                    dirVector.removeElementAt(dirVector.size()-1);
                } catch (ArrayIndexOutOfBoundsException aioobe) {
                     // "/../resource" Not allowed!
                     throw new IOException();
                }
                continue;
            }
            dirVector.addElement(curDir);
        }

        // save directory structure
        StringBuffer dirName = new StringBuffer();

        int nelements = dirVector.size();
        for (int i = 0; i < nelements; ++i) {
          dirName.append((String)dirVector.elementAt(i));
          dirName.append("/");
        }

        // save filename
        if (startIdx < name.length()) {
            String filename = name.substring(startIdx);
            // Throw IOE if the resource ends with ".class", but, not
            //  if the entire name is ".class"
            if ((filename.endsWith(".class")) &&
                (! ".class".equals(filename))) {
                throw new IOException();
            }
            dirName.append(name.substring(startIdx));
        }
        return dirName.toString();
    
private static native java.lang.Objectopen(java.lang.String name)

private static native intread(java.lang.Object handle)

public intread()
Reads the next byte of data from the input stream.

return
the next byte of data, or -1 if the end of the stream is reached.
exception
IOException if an I/O error occurs.

        int result;
        if ((result = read(handle)) != -1) {
            pos++;
        }
        return result;
    
public intread(byte[] b, int off, int len)

        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        }
        if (pos >= size) {
            return -1;
        }
        if (pos + len > size) {
            len = size - pos;
        }
        if (len <= 0) {
            return 0;
        }

        int readLength;
        if ((readLength = readBytes(handle, b, off, pos, len)) != -1) {
            pos += readLength;
        }
        return readLength;
    
private static native intreadBytes(java.lang.Object handle, byte[] b, int offset, int pos, int len)

private static native intsize(java.lang.Object handle)