diff --git a/classpath/avian/SystemClassLoader.java b/classpath/avian/SystemClassLoader.java index 71759c7a54..afdee82ed3 100644 --- a/classpath/avian/SystemClassLoader.java +++ b/classpath/avian/SystemClassLoader.java @@ -17,6 +17,7 @@ import java.util.Collection; import java.util.Collections; import java.util.ArrayList; import java.util.Enumeration; +import java.util.NoSuchElementException; public class SystemClassLoader extends ClassLoader { private native VMClass findVMClass(String name) @@ -114,12 +115,43 @@ public class SystemClassLoader extends ClassLoader { return Collections.enumeration(urls); } - protected Enumeration findResources(String name) { - Collection urls = new ArrayList(1); - URL url = findResource(name); - if (url != null) { - urls.add(url); + private class ResourceEnumeration implements Enumeration { + private long[] finderElementPtrPtr; + private String name, urlPrefix; + + public ResourceEnumeration(String name) { + this.name = name; + finderElementPtrPtr = new long[1]; + urlPrefix = nextResourceURLPrefix(); } - return Collections.enumeration(urls); + + private native String nextResourceURLPrefix(SystemClassLoader loader, + String name, long[] finderElementPtrPtr); + + private String nextResourceURLPrefix() { + return nextResourceURLPrefix(SystemClassLoader.this, name, + finderElementPtrPtr); + } + + public boolean hasMoreElements() { + return urlPrefix != null; + } + + public URL nextElement() { + if (urlPrefix == null) throw new NoSuchElementException(); + URL result; + try { + result = new URL(urlPrefix + name); + } catch (MalformedURLException ignored) { + result = null; + } + if (finderElementPtrPtr[0] == 0l) urlPrefix = null; + else urlPrefix = nextResourceURLPrefix(); + return result; + } + } + + protected Enumeration findResources(String name) { + return new ResourceEnumeration(name); } } diff --git a/src/builtin.cpp b/src/builtin.cpp index f7f9a28d53..7fda369dbf 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -152,6 +152,30 @@ Avian_avian_SystemClassLoader_resourceURLPrefix } } +extern "C" JNIEXPORT int64_t JNICALL +Avian_avian_SystemClassLoader_00024ResourceEnumeration_nextResourceURLPrefix +(Thread* t, object, uintptr_t* arguments) +{ + object loader = reinterpret_cast(arguments[1]); + object name = reinterpret_cast(arguments[2]); + object finderElementPtrPtr = reinterpret_cast(arguments[3]); + + if (LIKELY(name) && LIKELY(finderElementPtrPtr)) { + THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1); + stringChars(t, name, RUNTIME_ARRAY_BODY(n)); + + void *&finderElementPtr = reinterpret_cast(longArrayBody(t, + finderElementPtrPtr, 0)); + const char* name = static_cast + (systemClassLoaderFinder(t, loader))->nextUrlPrefix(RUNTIME_ARRAY_BODY(n), + finderElementPtr); + + return name ? reinterpret_cast(makeString(t, "%s", name)) : 0; + } else { + throwNew(t, Machine::NullPointerExceptionType); + } +} + extern "C" JNIEXPORT int64_t JNICALL Avian_avian_SystemClassLoader_getClass (Thread* t, object, uintptr_t* arguments)