diff -r f4a20d4f27c8 src/org/armedbear/lisp/Lisp.java --- a/src/org/armedbear/lisp/Lisp.java Fri Aug 28 12:55:00 2009 +0200 +++ b/src/org/armedbear/lisp/Lisp.java Sun Aug 30 00:58:47 2009 +0200 @@ -39,6 +39,7 @@ import java.io.InputStream; import java.lang.reflect.Constructor; import java.math.BigInteger; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.Hashtable; @@ -1074,8 +1075,20 @@ } if (device instanceof Pathname) { - // We're loading a fasl from j.jar. + // Are we loading a fasl from j.jar? + // XXX this will collide with file names from other JAR files URL url = Lisp.class.getResource(namestring); + if (url == null) { + // Maybe device-->namestring references another JAR file? + String jarFile = ((Pathname)device).getNamestring(); + if (jarFile.startsWith("jar:file:")) { + try { + url = new URL(jarFile + "!/" + namestring); + } catch (MalformedURLException ex) { + Debug.trace(ex); + } + } + } if (url != null) { try @@ -1111,6 +1124,20 @@ LispObject obj = loadCompiledFunction(in, (int) size); return obj != null ? obj : NIL; } + else + { + // ASSERT type = "abcl" + entryName + = defaultPathname.name.getStringValue() + + "." + "abcl";//defaultPathname.type.getStringValue(); + byte in[] + = Utilities + .getZippedZipEntryAsByteArray(zipFile, + entryName, + namestring); + LispObject o = loadCompiledFunction(in); + return o != null ? o : NIL; + } } finally { diff -r f4a20d4f27c8 src/org/armedbear/lisp/Load.java --- a/src/org/armedbear/lisp/Load.java Fri Aug 28 12:55:00 2009 +0200 +++ b/src/org/armedbear/lisp/Load.java Sun Aug 30 00:58:47 2009 +0200 @@ -33,6 +33,8 @@ package org.armedbear.lisp; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -43,6 +45,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; public final class Load extends Lisp { @@ -103,47 +106,94 @@ boolean returnLastResult) throws ConditionThrowable { - String dir = null; + InputStream in = null; + String zipFileName = null; + String zipEntryName = null; + String dir = null; + if (!Utilities.isFilenameAbsolute(filename)) { - dir = - coerceToPathname(Symbol.DEFAULT_PATHNAME_DEFAULTS.symbolValue()).getNamestring(); + dir = coerceToPathname(Symbol.DEFAULT_PATHNAME_DEFAULTS.symbolValue()).getNamestring(); } - File file = findLoadableFile(filename, dir); - if (file == null) { + // attempt to load from a jar file + if (filename.startsWith("jar:file:")) { + String s = new String(filename); + s = s.substring(9); + int index = s.lastIndexOf('!'); + if (index >= 0) { + zipFileName = s.substring(0, index); + zipEntryName = s.substring(index + 1); + if (zipEntryName.length() > 0 && zipEntryName.charAt(0) == '/') + zipEntryName = zipEntryName.substring(1); + if (Utilities.isPlatformWindows) { + if (zipFileName.length() > 0 && zipFileName.charAt(0) == '/') + zipFileName = zipFileName.substring(1); + } + } + } + + File file = findLoadableFile(filename, dir); + if (null == file && null == zipFileName) { if (ifDoesNotExist) - return error(new FileError("File not found: " + filename, - pathname)); + return error(new FileError("File not found: " + filename, pathname)); else return NIL; } + if (checkZipFile(file)) { + zipFileName = file.getPath(); + zipEntryName = file.getName(); + } + + String truename = filename; + ZipFile zipfile = null; - filename = file.getPath(); - ZipFile zipfile = null; - if (checkZipFile(file)) - { + if (zipFileName != null) { try { - zipfile = ZipCache.getZip(file.getPath()); + zipfile = ZipCache.getZip(zipFileName); } catch (Throwable t) { - // Fall through. + return error (new FileError("Zip file not found: " + filename, pathname)); } - } - String truename = filename; - InputStream in = null; - if (zipfile != null) { - String name = file.getName(); - int index = name.lastIndexOf('.'); - Debug.assertTrue(index >= 0); - name = name.substring(0, index).concat("._"); - ZipEntry entry = zipfile.getEntry(name); - if (entry != null) { - try { + ZipEntry entry = zipfile.getEntry(zipEntryName); + if (null == entry) { + // try appending "._" to base filename + int index = zipEntryName.lastIndexOf('.'); + if (-1 == index) index = zipEntryName.length(); + zipEntryName = zipEntryName.substring(0, index).concat("._"); + entry = zipfile.getEntry(zipEntryName); + } + if (null == entry) { + // try appending ".abcl" to base filename + int index = zipEntryName.lastIndexOf('.'); + if (index == -1) + index = zipEntryName.length(); + zipEntryName = zipEntryName.substring(0, index).concat(".abcl"); + entry = zipfile.getEntry(zipEntryName); + if (entry == null) { + return error(new LispError("Failed to find " + zipEntryName + " in " + + zipFileName + ".")); + } + + // Now we have to seek for the ._ file + int i = zipEntryName.lastIndexOf('.'); + String subZipEntryName = zipEntryName.substring(0, i).concat("._"); + in = Utilities.getZippedZipEntryAsInputStream(zipfile, + zipEntryName, + subZipEntryName); + + // XXX Help out the truename loading + // truename += ".abcl"; + } + if (null == entry) { + return error(new FileError("Can't read zip file entry " + zipEntryName, pathname)); + } + try { + if (in == null) { in = zipfile.getInputStream(entry); } - catch (IOException e) { - return error(new LispError(e.getMessage())); - } + } + catch (IOException e) { + return error(new LispError(e.getMessage())); } } else { try { @@ -162,7 +212,8 @@ } } try { - return loadFileFromStream(null, truename, + + return loadFileFromStream(null, truename, new Stream(in, Symbol.CHARACTER), verbose, print, false, returnLastResult); } diff -r f4a20d4f27c8 src/org/armedbear/lisp/Utilities.java --- a/src/org/armedbear/lisp/Utilities.java Fri Aug 28 12:55:00 2009 +0200 +++ b/src/org/armedbear/lisp/Utilities.java Sun Aug 30 00:58:47 2009 +0200 @@ -33,8 +33,14 @@ package org.armedbear.lisp; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; public final class Utilities extends Lisp { @@ -115,4 +121,60 @@ return null; } } + + public static byte[] getZippedZipEntryAsByteArray(ZipFile zipfile, + String entryName, + String subEntryName) + throws ConditionThrowable + { + ZipEntry entry = zipfile.getEntry(entryName); + + ZipInputStream stream = null; + try { + stream = new ZipInputStream(zipfile.getInputStream(entry)); + } + catch (IOException e) { + Lisp.error(new FileError("Failed to open '" + entryName + "' in zipfile '" + + zipfile + "': " + e.getMessage())); + } + // XXX Cache the zipEntries somehow + do { + try { + entry = stream.getNextEntry(); + } catch (IOException e){ + Lisp.error(new FileError("Failed to seek for '" + subEntryName + + "' in '" + + zipfile.getName() + ":" + entryName + ".:" + + e.getMessage())); + } + } while (!entry.getName().equals(subEntryName)); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int count; + byte buf[] = new byte[1024]; + try { + while ((count = stream.read(buf, 0, buf.length)) != -1) { + buffer.write(buf, 0, count); + } + } catch (java.io.IOException e) { + Lisp.error(new FileError("Failed to read compressed '" + + subEntryName + + "' in '" + + zipfile.getName() + ":" + entryName + ":" + + e.getMessage())); + } + return buffer.toByteArray(); + } + + public static InputStream getZippedZipEntryAsInputStream(ZipFile zipfile, + String entryName, + String subEntryName) + throws ConditionThrowable + { + return + new ByteArrayInputStream(Utilities + .getZippedZipEntryAsByteArray(zipfile, entryName, + subEntryName)); + } } +