From: Sam Ruby Date: Sat, 22 Jul 2000 20:36:11 +0000 (+0000) Subject: Complete the work mapping arrays and hashtables X-Git-Tag: PRE_FILE_COMPILE_API_CHANGE~189 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4e94a50301e9c55b5ef62640bb59597272bba52;p=php Complete the work mapping arrays and hashtables --- diff --git a/ext/java/README b/ext/java/README index 097bfabf1a..52dadd0a89 100644 --- a/ext/java/README +++ b/ext/java/README @@ -40,6 +40,12 @@ What is PHP4 ext/java? possibly with a loss of data (example: double precision floating point numbers will be converted to boolean). + 6) In the tradition of PHP, arrays and hashtables may pretty much + be used interchangably. Note that hashtables in PHP may only be + indexed by integers or strings; and that arrays of primitive types + in Java can not be sparse. Also note that these constructs are + passed by value, so may be expensive in terms of memory and time. + Build and execution instructions: Given the number of platforms and providers of JVMs, no single set of diff --git a/ext/java/java.c b/ext/java/java.c index c56bff5bdc..ab9dcf172e 100644 --- a/ext/java/java.c +++ b/ext/java/java.c @@ -730,6 +730,17 @@ JNIEXPORT jlong JNICALL Java_net_php_reflect_nextElement return (jlong)(long)result; } +JNIEXPORT jlong JNICALL Java_net_php_reflect_hashIndexUpdate + (JNIEnv *jenv, jclass self, jlong array, jlong key) +{ + pval *result; + pval *handle = (pval*)(long)array; + ALLOC_ZVAL(result); + zend_hash_index_update(handle->value.ht, (unsigned long)key, + &result, sizeof(zval *), NULL); + return (jlong)(long)result; +} + JNIEXPORT jlong JNICALL Java_net_php_reflect_hashUpdate (JNIEnv *jenv, jclass self, jlong array, jbyteArray key) { diff --git a/ext/java/reflect.java b/ext/java/reflect.java index d5e9393dc2..3520b2aba8 100644 --- a/ext/java/reflect.java +++ b/ext/java/reflect.java @@ -46,6 +46,7 @@ public class reflect { private static native void setResultFromArray(long result); private static native long nextElement(long array); private static native long hashUpdate(long array, byte key[]); + private static native long hashIndexUpdate(long array, long key); private static native void setException(long result, byte value[]); public static native void setEnv(); @@ -88,7 +89,13 @@ public class reflect { setResultFromArray(result); for (Enumeration e = ht.keys(); e.hasMoreElements(); ) { Object key = e.nextElement(); - setResult(hashUpdate(result, key.toString().getBytes()), ht.get(key)); + long slot; + if (key instanceof Number && + !(key instanceof Double || key instanceof Float)) + slot = hashIndexUpdate(result, ((Number)key).longValue()); + else + slot = hashUpdate(result, key.toString().getBytes()); + setResult(slot, ht.get(key)); } } else { @@ -176,8 +183,13 @@ public class reflect { if (!c.isInstance(args[i])) break; weight++; } - } else if (parms[i].isInstance("")) { - if (!(args[i] instanceof byte[])) + } else if (parms[i].isAssignableFrom(java.lang.String.class)) { + if (!(args[i] instanceof byte[]) && !(args[i] instanceof String)) + weight+=9999; + } else if (parms[i].isArray()) { + if (args[i] instanceof java.util.Hashtable) + weight+=256; + else weight+=9999; } else if (parms[i].isPrimitive()) { Class c=parms[i]; @@ -235,6 +247,42 @@ public class reflect { if (c == Float.TYPE) result[i]=new Float(n.floatValue()); if (c == Long.TYPE && !(n instanceof Long)) result[i]=new Long(n.longValue()); + } else if (args[i] instanceof Hashtable && parms[i].isArray()) { + try { + Hashtable ht = (Hashtable)args[i]; + int size = ht.size(); + + // Verify that the keys are Long, and determine maximum + for (Enumeration e = ht.keys(); e.hasMoreElements(); ) { + int index = ((Long)e.nextElement()).intValue(); + if (index >= size) size = index+1; + } + + Object tempArray[] = new Object[size]; + Class tempTarget[] = new Class[size]; + Class targetType = parms[i].getComponentType(); + + // flatten the hash table into an array + for (int j=0; jvalue.ht, (unsigned long)key, + &result, sizeof(zval *), NULL); + return (jlong)(long)result; +} + JNIEXPORT jlong JNICALL Java_net_php_reflect_hashUpdate (JNIEnv *jenv, jclass self, jlong array, jbyteArray key) { diff --git a/ext/rpc/java/reflect.java b/ext/rpc/java/reflect.java index d5e9393dc2..3520b2aba8 100644 --- a/ext/rpc/java/reflect.java +++ b/ext/rpc/java/reflect.java @@ -46,6 +46,7 @@ public class reflect { private static native void setResultFromArray(long result); private static native long nextElement(long array); private static native long hashUpdate(long array, byte key[]); + private static native long hashIndexUpdate(long array, long key); private static native void setException(long result, byte value[]); public static native void setEnv(); @@ -88,7 +89,13 @@ public class reflect { setResultFromArray(result); for (Enumeration e = ht.keys(); e.hasMoreElements(); ) { Object key = e.nextElement(); - setResult(hashUpdate(result, key.toString().getBytes()), ht.get(key)); + long slot; + if (key instanceof Number && + !(key instanceof Double || key instanceof Float)) + slot = hashIndexUpdate(result, ((Number)key).longValue()); + else + slot = hashUpdate(result, key.toString().getBytes()); + setResult(slot, ht.get(key)); } } else { @@ -176,8 +183,13 @@ public class reflect { if (!c.isInstance(args[i])) break; weight++; } - } else if (parms[i].isInstance("")) { - if (!(args[i] instanceof byte[])) + } else if (parms[i].isAssignableFrom(java.lang.String.class)) { + if (!(args[i] instanceof byte[]) && !(args[i] instanceof String)) + weight+=9999; + } else if (parms[i].isArray()) { + if (args[i] instanceof java.util.Hashtable) + weight+=256; + else weight+=9999; } else if (parms[i].isPrimitive()) { Class c=parms[i]; @@ -235,6 +247,42 @@ public class reflect { if (c == Float.TYPE) result[i]=new Float(n.floatValue()); if (c == Long.TYPE && !(n instanceof Long)) result[i]=new Long(n.longValue()); + } else if (args[i] instanceof Hashtable && parms[i].isArray()) { + try { + Hashtable ht = (Hashtable)args[i]; + int size = ht.size(); + + // Verify that the keys are Long, and determine maximum + for (Enumeration e = ht.keys(); e.hasMoreElements(); ) { + int index = ((Long)e.nextElement()).intValue(); + if (index >= size) size = index+1; + } + + Object tempArray[] = new Object[size]; + Class tempTarget[] = new Class[size]; + Class targetType = parms[i].getComponentType(); + + // flatten the hash table into an array + for (int j=0; j