/* * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden * Distributed under the terms shown in the file COPYRIGHT * found in the root folder of this project or at * http://eng.tada.se/osprojects/COPYRIGHT.html * * @author Thomas Hallgren */ #include "pljava/Exception.h" #include "pljava/type/Type_priv.h" static jclass s_byteArray_class; static jclass s_BlobValue_class; static jmethodID s_BlobValue_length; static jmethodID s_BlobValue_getContents; /* * byte[] type. Copies data to/from a bytea struct. */ static jvalue _byte_array_coerceDatum(Type self, Datum arg) { jvalue result; bytea* bytes = DatumGetByteaP(arg); jsize length = VARSIZE(bytes) - VARHDRSZ; jbyteArray ba = JNI_newByteArray(length); JNI_setByteArrayRegion(ba, 0, length, (jbyte*)VARDATA(bytes)); result.l = ba; return result; } static Datum _byte_array_coerceObject(Type self, jobject byteArray) { bytea* bytes = 0; if(byteArray == 0) return 0; if(JNI_isInstanceOf(byteArray, s_byteArray_class)) { jsize length = JNI_getArrayLength((jarray)byteArray); int32 byteaSize = length + VARHDRSZ; bytes = (bytea*)palloc(byteaSize); #if (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER < 3) VARATT_SIZEP(bytes) = byteaSize; #else SET_VARSIZE(bytes, byteaSize); #endif JNI_getByteArrayRegion((jbyteArray)byteArray, 0, length, (jbyte*)VARDATA(bytes)); } else if(JNI_isInstanceOf(byteArray, s_BlobValue_class)) { jobject byteBuffer; int32 byteaSize; jlong length = JNI_callLongMethod(byteArray, s_BlobValue_length); byteaSize = (int32)(length + VARHDRSZ); bytes = (bytea*)palloc(byteaSize); #if (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER < 3) VARATT_SIZEP(bytes) = byteaSize; #else SET_VARSIZE(bytes, byteaSize); #endif byteBuffer = JNI_newDirectByteBuffer((void*)VARDATA(bytes), length); if(byteBuffer != 0) JNI_callVoidMethod(byteArray, s_BlobValue_getContents, byteBuffer); JNI_deleteLocalRef(byteBuffer); } else { Exception_throwIllegalArgument("Not coercable to bytea"); } PG_RETURN_BYTEA_P(bytes); } /* Make this datatype available to the postgres system. */ extern void byte_array_initialize(void); void byte_array_initialize(void) { TypeClass cls = TypeClass_alloc("type.byte[]"); cls->JNISignature = "[B"; cls->javaTypeName = "byte[]"; cls->coerceDatum = _byte_array_coerceDatum; cls->coerceObject = _byte_array_coerceObject; Type_registerType("byte[]", TypeClass_allocInstance(cls, BYTEAOID)); s_byteArray_class = JNI_newGlobalRef(PgObject_getJavaClass("[B")); s_BlobValue_class = JNI_newGlobalRef(PgObject_getJavaClass("org/postgresql/pljava/jdbc/BlobValue")); s_BlobValue_length = PgObject_getJavaMethod(s_BlobValue_class, "length", "()J"); s_BlobValue_getContents = PgObject_getJavaMethod(s_BlobValue_class, "getContents", "(Ljava/nio/ByteBuffer;)V"); }