#include "bulkio.h" #include "array-byteswap.h" #include "java_array_methods.h" #include "native-utils.h" #include "layout!Pjint.h" #include "layout!PTAjbyte.h" #include "layout!LTAjbyte.h" #include "layout!TAjbyte.h" #include "layout!Pjbyte.h" #include "layout!Ljbyte.h" /* This file is not meant to be compiled directly it is included by various bulk io native code files to provide a shared implementation of the primitives */ /* ------------------------------------------------------------------------------------ */ /* array element sizes that need to be byte-swapped on a little-endian platform */ #define IS_SWAPPABLE_SIZE(sz) (sz == 2 || sz == 4 || sz == 8) /* TODO: implement platform-independent on-disk rep. for arrays of immutables (need more detailed type info about immutable contents to do this) */ /* ------------------------------------------------------------------------------------ */ #ifdef BULKIO_READFUNC_HEADER BULKIO_READFUNC_HEADER { PTAjbyte a_array; jint isatomic; jint savelength; jint savesize; Pjint psize; Pjint plength; CHECK_NULL_GLOBAL(me); CHECK_NULL_GLOBAL(primjavaarray); if (bounds_checking && !IS_JAVA_ARRAY_GLOBAL(primjavaarray)) tossIllegalArgumentException_str("Bulk I/O may only be performed on Java Arrays"); a_array = * (PTAjbyte *) &primjavaarray; JAVA_ARRAY_INFO_GLOBAL( savelength, savesize, isatomic, a_array ); if (!isatomic) tossIllegalArgumentException_str("Bulk I/O may only be performed on arrays of primitive (non-reference) types"); DEBUGMSG2("array: elemsz = %i length = %i", savesize, savelength); if (count == -1) { /* means select to the end of array */ count = savelength - arrayoffset; } DEBUGMSG2("parameters: arrayoffset = %i count = %i", arrayoffset, count); if (bounds_checking) JAVA_ARRAY_LENCHECK( savelength, arrayoffset, count, "in bulkI/O read" ); #if PORTABLE_ONDISK_REPRESENTATION && !defined(WORDS_BIGENDIAN) if (IS_SWAPPABLE_SIZE(savesize) && !isDirectlyAddressable(a_array)) { /* need to read and byte-swap to a global array */ LTAjbyte tmp_array; PTAjbyte glob_tmp_array; Ljbyte from_data_bytes; Pjbyte to_data_bytes; /* allocate a byte array that's just big enough to hold the selected subarray */ JAVA_ARRAY_ALLOC(tmp_array, 0, savesize * count, jbyte, 1, 1); globalize(glob_tmp_array, tmp_array); DEBUGMSG("Calling super.read()"); BULKIO_READFUNC_CALLSUPER(me, glob_tmp_array, 0, count * savesize); DEBUGMSG("Returned from super.read()"); /* get a global byte ptr to just the bytes we need to swap/copy */ FIELD_ADDR_LOCAL( from_data_bytes, tmp_array, data[0] ); /* get ptr to data */ /* get a global byte ptr for our dest array */ FIELD_ADDR_GLOBAL( to_data_bytes, a_array, data[0] ); /* get ptr to data */ INDEX_GLOBAL( to_data_bytes, to_data_bytes, savesize * arrayoffset ); /* advance ptr to correct offset */ /* swap and copy selected sub-array to the global array */ DEBUGMSG("Calling ARRAY_BYTE_SWAP_GLOBAL()"); ARRAY_BYTE_SWAP_LOCAL(from_data_bytes, savesize, count); /* perform conversion */ local_to_global_copy( from_data_bytes, to_data_bytes, savesize * count ); } else #endif { /* note this bracket may correspond to else stmt above */ jint tmpval; /* cast this array to a byte array */ FIELD_ADDR_GLOBAL( plength, a_array, header.length ); /* get ptr to length */ FIELD_ADDR_GLOBAL( psize, a_array, header.size ); /* get ptr to size */ tmpval = (savelength * savesize); FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(plength, tmpval); FENCE_POST_WRITE(); tmpval = sizeof(jbyte); FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(psize, tmpval); FENCE_POST_WRITE(); /* call the superclass read function on the byte array */ DEBUGMSG("Calling super.read()"); BULKIO_READFUNC_CALLSUPER(me, a_array, arrayoffset * savesize, count * savesize); DEBUGMSG("Returned from super.read()"); /* cast array back - restore parameters */ FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(plength, savelength); FENCE_POST_WRITE(); FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(psize, savesize); FENCE_POST_WRITE(); #if PORTABLE_ONDISK_REPRESENTATION && !defined(WORDS_BIGENDIAN) if (IS_SWAPPABLE_SIZE(savesize)) { /* need to convert */ Pjbyte data_bytes; FIELD_ADDR_GLOBAL( data_bytes, a_array, data[0] ); /* get ptr to data */ INDEX_GLOBAL( data_bytes, data_bytes, savesize * arrayoffset ); /* advance ptr to correct offset */ /* perform conversion (will always be local) */ ARRAY_BYTE_SWAP_GLOBAL(data_bytes, savesize, count); } #endif } return; } #endif /* ------------------------------------------------------------------------------------ */ #ifdef BULKIO_WRITEFUNC_HEADER BULKIO_WRITEFUNC_HEADER { PTAjbyte a_array; jint isatomic; jint savelength; jint savesize; Pjint psize; Pjint plength; CHECK_NULL_GLOBAL(me); CHECK_NULL_GLOBAL(primjavaarray); if (bounds_checking && !IS_JAVA_ARRAY_GLOBAL(primjavaarray)) tossIllegalArgumentException_str("Bulk I/O may only be performed on Java Arrays"); a_array = * (PTAjbyte *) &primjavaarray; JAVA_ARRAY_INFO_GLOBAL( savelength, savesize, isatomic, a_array ); if (!isatomic) tossIllegalArgumentException_str("Bulk I/O may only be performed on arrays of primitive (non-reference) types"); DEBUGMSG2("array: elemsz = %i length = %i", savesize, savelength); if (count == -1) { /* means select to the end of array */ count = savelength - arrayoffset; } DEBUGMSG2("parameters: arrayoffset = %i count = %i", arrayoffset, count); if (bounds_checking) JAVA_ARRAY_LENCHECK( savelength, arrayoffset, count, "in bulkI/O write" ); #if PORTABLE_ONDISK_REPRESENTATION && !defined(WORDS_BIGENDIAN) if (IS_SWAPPABLE_SIZE(savesize)) { /* we need to swap bytes before writing */ LTAjbyte tmp_array; PTAjbyte glob_tmp_array; Pjbyte from_data_bytes; Pjbyte to_data_bytes; /* allocate a local array just big enough to hold the selected sub-array */ JAVA_ARRAY_ALLOC(tmp_array, 0, savesize * count, jbyte, 1, 1); globalize(glob_tmp_array, tmp_array); /* get a global byte ptr to just the bytes we need to write */ FIELD_ADDR_GLOBAL( from_data_bytes, a_array, data[0] ); /* get ptr to data */ INDEX_GLOBAL( from_data_bytes, from_data_bytes, savesize * arrayoffset ); /* advance ptr to correct offset */ /* get a global byte ptr for our temp array */ FIELD_ADDR_GLOBAL( to_data_bytes, glob_tmp_array, data[0] ); /* get ptr to data */ /* swap/copy selected sub-array into the (local) temp array */ DEBUGMSG("Calling ARRAY_COPY_BYTE_SWAP_GLOBAL()"); ARRAY_COPY_BYTE_SWAP_GLOBAL(to_data_bytes, from_data_bytes, savesize, count); /* perform conversion */ /* write the converted local bytes */ DEBUGMSG("Calling super.write()"); BULKIO_WRITEFUNC_CALLSUPER(me, glob_tmp_array, 0, count * savesize); DEBUGMSG("Returned from super.write()"); } else #endif { /* note this bracket may correspond to else stmt above */ jint tmpval; /* cast this array to a byte array */ FIELD_ADDR_GLOBAL( plength, a_array, header.length ); /* get ptr to length */ FIELD_ADDR_GLOBAL( psize, a_array, header.size ); /* get ptr to size */ tmpval = (savelength * savesize); FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(plength, tmpval); FENCE_POST_WRITE(); tmpval = sizeof(jbyte); FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(psize, tmpval); FENCE_POST_WRITE(); /* call the superclass write function on the byte array */ DEBUGMSG("Calling super.write()"); BULKIO_WRITEFUNC_CALLSUPER(me, a_array, arrayoffset * savesize, count * savesize); DEBUGMSG("Returned from super.write()"); /* cast array back - restore parameters */ FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(plength, savelength); FENCE_POST_WRITE(); FENCE_PRE_WRITE(); ASSIGN_GLOBAL_jint(psize, savesize); FENCE_POST_WRITE(); } return; } #endif /* ------------------------------------------------------------------------------------ */