diff options
author | Sam Ruby <rubys@php.net> | 2000-07-22 20:36:11 +0000 |
---|---|---|
committer | Sam Ruby <rubys@php.net> | 2000-07-22 20:36:11 +0000 |
commit | f4e94a50301e9c55b5ef62640bb59597272bba52 (patch) | |
tree | 9f618720d557a6af936b82d77949cadabe913826 | |
parent | 668af98d753aa2991af11e0b2a0469559097eead (diff) | |
download | php-git-f4e94a50301e9c55b5ef62640bb59597272bba52.tar.gz |
Complete the work mapping arrays and hashtables
-rw-r--r-- | ext/java/README | 6 | ||||
-rw-r--r-- | ext/java/java.c | 11 | ||||
-rw-r--r-- | ext/java/reflect.java | 54 | ||||
-rw-r--r-- | ext/rpc/java/README | 6 | ||||
-rw-r--r-- | ext/rpc/java/java.c | 11 | ||||
-rw-r--r-- | ext/rpc/java/reflect.java | 54 |
6 files changed, 136 insertions, 6 deletions
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; j<size; j++) { + tempArray[j] = ht.get(new Long(j)); + if (tempArray[j] == null && targetType.isPrimitive()) + throw new Exception("bail"); + tempTarget[j] = targetType; + } + + // coerce individual elements into the target type + Object coercedArray[] = coerce(tempTarget, tempArray); + + // copy the results into the desired array type + Object array = Array.newInstance(targetType,size); + for (int j=0; j<size; j++) { + Array.set(array, j, coercedArray[j]); + } + + result[i]=array; + } catch (Exception e) { + // leave result[i] alone... + } } } return result; diff --git a/ext/rpc/java/README b/ext/rpc/java/README index 097bfabf1a..52dadd0a89 100644 --- a/ext/rpc/java/README +++ b/ext/rpc/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/rpc/java/java.c b/ext/rpc/java/java.c index c56bff5bdc..ab9dcf172e 100644 --- a/ext/rpc/java/java.c +++ b/ext/rpc/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/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<size; j++) { + tempArray[j] = ht.get(new Long(j)); + if (tempArray[j] == null && targetType.isPrimitive()) + throw new Exception("bail"); + tempTarget[j] = targetType; + } + + // coerce individual elements into the target type + Object coercedArray[] = coerce(tempTarget, tempArray); + + // copy the results into the desired array type + Object array = Array.newInstance(targetType,size); + for (int j=0; j<size; j++) { + Array.set(array, j, coercedArray[j]); + } + + result[i]=array; + } catch (Exception e) { + // leave result[i] alone... + } } } return result; |