forked from tada/pljava
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbyte_array.c
More file actions
94 lines (83 loc) · 2.75 KB
/
Copy pathbyte_array.c
File metadata and controls
94 lines (83 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
* 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");
}