1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_connectivity.hxx"
26 #include "hsqldb/HStorageAccess.hxx"
27 #include <comphelper/processfactory.hxx>
28 #include <com/sun/star/embed/XStorage.hpp>
29 #include <com/sun/star/embed/ElementModes.hpp>
30 #include <com/sun/star/io/XStream.hpp>
31 #include "hsqldb/HStorageMap.hxx"
32 #include "hsqldb/StorageNativeInputStream.h"
33 #include "accesslog.hxx"
34 #include "diagnose_ex.h"
35
36 #include <string.h>
37
38 using namespace ::com::sun::star::container;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::embed;
41 using namespace ::com::sun::star::io;
42 using namespace ::com::sun::star::lang;
43 using namespace ::connectivity::hsqldb;
44
45 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
46 #define ThrowException(env, type, msg) { \
47 env->ThrowNew(env->FindClass(type), msg); }
48
49 /*
50 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
51 * Method: openStream
52 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
53 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_openStream(JNIEnv * env,jobject,jstring name,jstring key,jint mode)54 SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_openStream
55 (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key, jint mode)
56 {
57 #ifdef HSQLDB_DBG
58 {
59 OperationLogFile( env, name, "data" ).logOperation( "openStream" );
60 LogFile( env, name, "data" ).create();
61 }
62 #endif
63
64 StorageContainer::registerStream(env,name,key,mode);
65 }
66 // -----------------------------------------------------------------------------
67 /*
68 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
69 * Method: close
70 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
71 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_close(JNIEnv * env,jobject,jstring name,jstring key)72 SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_close
73 (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key)
74 {
75 #ifdef HSQLDB_DBG
76 {
77 ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key);
78 ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name);
79 }
80 #endif
81 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
82 Reference< XOutputStream> xFlush = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>();
83 if ( xFlush.is() )
84 try
85 {
86 xFlush->flush();
87 }
88 catch(Exception&)
89 {
90 OSL_ENSURE( false, "NativeStorageAccess::close: caught an exception while flushing!" );
91 }
92 #ifdef HSQLDB_DBG
93 {
94 OperationLogFile aOpLog( env, name, "data" );
95 aOpLog.logOperation( "close" );
96 aOpLog.close();
97
98 LogFile aDataLog( env, name, "data" );
99 aDataLog.close();
100 }
101 #endif
102
103 StorageContainer::revokeStream(env,name,key);
104 }
105 // -----------------------------------------------------------------------------
106 /*
107 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
108 * Method: getFilePointer
109 * Signature: (Ljava/lang/String;Ljava/lang/String;)J
110 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_getFilePointer(JNIEnv * env,jobject,jstring name,jstring key)111 SAL_DLLPUBLIC_EXPORT jlong JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_getFilePointer
112 (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key)
113 {
114 #ifdef HSQLDB_DBG
115 OperationLogFile aOpLog( env, name, "data" );
116 aOpLog.logOperation( "getFilePointer" );
117 #endif
118
119 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
120 OSL_ENSURE(pHelper.get(),"No stream helper!");
121
122 jlong nReturn = pHelper.get() ? pHelper->getSeek()->getPosition() : jlong(0);
123 #ifdef HSQLDB_DBG
124 aOpLog.logReturn( nReturn );
125 #endif
126 return nReturn;
127 }
128 // -----------------------------------------------------------------------------
129
130 /*
131 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
132 * Method: length
133 * Signature: (Ljava/lang/String;Ljava/lang/String;)J
134 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_length(JNIEnv * env,jobject,jstring name,jstring key)135 SAL_DLLPUBLIC_EXPORT jlong JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_length
136 (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key)
137 {
138 #ifdef HSQLDB_DBG
139 OperationLogFile aOpLog( env, name, "data" );
140 aOpLog.logOperation( "length" );
141 #endif
142
143 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
144 OSL_ENSURE(pHelper.get(),"No stream helper!");
145
146 jlong nReturn = pHelper.get() ? pHelper->getSeek()->getLength() :jlong(0);
147 #ifdef HSQLDB_DBG
148 aOpLog.logReturn( nReturn );
149 #endif
150 return nReturn;
151 }
152
153 // -----------------------------------------------------------------------------
154
read_from_storage_stream(JNIEnv * env,jobject,jstring name,jstring key,DataLogFile * logger)155 jint read_from_storage_stream( JNIEnv * env, jobject /*obj_this*/, jstring name, jstring key, DataLogFile* logger )
156 {
157 OSL_UNUSED( logger );
158 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
159 Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>();
160 OSL_ENSURE(xIn.is(),"Input stream is NULL!");
161 if ( xIn.is() )
162 {
163 Sequence< ::sal_Int8 > aData(1);
164 sal_Int32 nBytesRead = -1;
165 try
166 {
167 nBytesRead = xIn->readBytes(aData,1);
168 }
169 catch(Exception& e)
170 {
171 StorageContainer::throwJavaException(e,env);
172 return -1;
173
174 }
175 if (nBytesRead <= 0)
176 {
177 return (-1);
178 }
179 else
180 {
181 sal_Int32 tmpInt = aData[0];
182 if (tmpInt < 0 )
183 tmpInt = 256 +tmpInt;
184
185 #ifdef HSQLDB_DBG
186 if ( logger )
187 logger->write( tmpInt );
188 #endif
189 return(tmpInt);
190 }
191 }
192 return -1;
193 }
194
195 // -----------------------------------------------------------------------------
196
197 /*
198 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
199 * Method: read
200 * Signature: (Ljava/lang/String;Ljava/lang/String;)I
201 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2(JNIEnv * env,jobject obj_this,jstring name,jstring key)202 SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2
203 (JNIEnv* env, jobject obj_this, jstring name, jstring key)
204 {
205 #ifdef HSQLDB_DBG
206 OperationLogFile aOpLog( env, name, "data" );
207 aOpLog.logOperation( "read" );
208
209 DataLogFile aDataLog( env, name, "data" );
210 return read_from_storage_stream( env, obj_this, name, key, &aDataLog );
211 #else
212 return read_from_storage_stream( env, obj_this, name, key );
213 #endif
214 }
215
216 // -----------------------------------------------------------------------------
217
read_from_storage_stream_into_buffer(JNIEnv * env,jobject,jstring name,jstring key,jbyteArray buffer,jint off,jint len,DataLogFile * logger)218 jint read_from_storage_stream_into_buffer( JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key, jbyteArray buffer, jint off, jint len, DataLogFile* logger )
219 {
220 OSL_UNUSED( logger );
221 #ifdef HSQLDB_DBG
222 {
223 ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key);
224 ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name);
225 }
226 #endif
227 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
228 Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>();
229 OSL_ENSURE(xIn.is(),"Input stream is NULL!");
230 if ( xIn.is() )
231 {
232 jsize nLen = env->GetArrayLength(buffer);
233 if ( nLen < len || len <= 0 )
234 {
235 ThrowException( env,
236 "java/io/IOException",
237 "len is greater or equal to the buffer size");
238 return -1;
239 }
240 sal_Int32 nBytesRead = -1;
241
242 Sequence< ::sal_Int8 > aData(nLen);
243 try
244 {
245 nBytesRead = xIn->readBytes(aData, len);
246 }
247 catch(Exception& e)
248 {
249 StorageContainer::throwJavaException(e,env);
250 return -1;
251 }
252
253 if (nBytesRead <= 0)
254 return -1;
255 env->SetByteArrayRegion(buffer,off,nBytesRead,&aData[0]);
256
257 #ifdef HSQLDB_DBG
258 if ( logger )
259 logger->write( aData.getConstArray(), nBytesRead );
260 #endif
261 return nBytesRead;
262 }
263 ThrowException( env,
264 "java/io/IOException",
265 "Stream is not valid");
266 return -1;
267 }
268 // -----------------------------------------------------------------------------
269
270 /*
271 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
272 * Method: read
273 * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)I
274 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2_3BII(JNIEnv * env,jobject obj_this,jstring name,jstring key,jbyteArray buffer,jint off,jint len)275 SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2_3BII
276 (JNIEnv * env, jobject obj_this,jstring name, jstring key, jbyteArray buffer, jint off, jint len)
277 {
278 #ifdef HSQLDB_DBG
279 OperationLogFile aOpLog( env, name, "data" );
280 aOpLog.logOperation( "read( byte[], int, int )" );
281
282 DataLogFile aDataLog( env, name, "data" );
283 return read_from_storage_stream_into_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog );
284 #else
285 return read_from_storage_stream_into_buffer( env, obj_this, name, key, buffer, off, len );
286 #endif
287 }
288
289 // -----------------------------------------------------------------------------
290
291 /*
292 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
293 * Method: readInt
294 * Signature: (Ljava/lang/String;Ljava/lang/String;)I
295 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_readInt(JNIEnv * env,jobject,jstring name,jstring key)296 SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_readInt
297 (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key)
298 {
299 #ifdef HSQLDB_DBG
300 OperationLogFile aOpLog( env, name, "data" );
301 aOpLog.logOperation( "readInt" );
302 #endif
303
304 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
305 Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>();
306 OSL_ENSURE(xIn.is(),"Input stream is NULL!");
307 if ( xIn.is() )
308 {
309 Sequence< ::sal_Int8 > aData(4);
310 sal_Int32 nBytesRead = -1;
311 try
312 {
313 nBytesRead = xIn->readBytes(aData, 4);
314 }
315 catch(Exception& e)
316 {
317 StorageContainer::throwJavaException(e,env);
318 return -1;
319 }
320
321 if ( nBytesRead != 4 ) {
322 ThrowException( env,
323 "java/io/IOException",
324 "Bytes read != 4");
325 return -1;
326 }
327
328 Sequence< sal_Int32 > ch(4);
329 for(sal_Int32 i = 0;i < 4; ++i)
330 {
331 ch[i] = aData[i];
332 if (ch[i] < 0 )
333 ch[i] = 256 + ch[i];
334 }
335
336 if ((ch[0] | ch[1] | ch[2] | ch[3]) < 0)
337 {
338 ThrowException( env,
339 "java/io/IOException",
340 "One byte is < 0");
341 return -1;
342 }
343 jint nRet = ((ch[0] << 24) + (ch[1] << 16) + (ch[2] << 8) + (ch[3] << 0));
344 #ifdef HSQLDB_DBG
345 DataLogFile aDataLog( env, name, "data" );
346 aDataLog.write( nRet );
347
348 aOpLog.logReturn( nRet );
349 #endif
350 return nRet;
351 }
352 ThrowException( env,
353 "java/io/IOException",
354 "No InputStream");
355 return -1;
356 }
357 // -----------------------------------------------------------------------------
358
359 /*
360 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
361 * Method: seek
362 * Signature: (Ljava/lang/String;Ljava/lang/String;J)V
363 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_seek(JNIEnv * env,jobject,jstring name,jstring key,jlong position)364 SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_seek
365 (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key, jlong position)
366 {
367 #ifdef HSQLDB_DBG
368 OperationLogFile aOpLog( env, name, "data" );
369 aOpLog.logOperation( "seek", position );
370 #endif
371
372 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
373 Reference< XSeekable> xSeek = pHelper.get() ? pHelper->getSeek() : Reference< XSeekable>();
374
375 OSL_ENSURE(xSeek.is(),"No Seekable stream!");
376 if ( xSeek.is() )
377 {
378 #ifdef HSQLDB_DBG
379 DataLogFile aDataLog( env, name, "data" );
380 #endif
381
382 ::sal_Int64 nLen = xSeek->getLength();
383 if ( nLen < position)
384 {
385 static ::sal_Int64 BUFFER_SIZE = 9192;
386 #ifdef HSQLDB_DBG
387 aDataLog.seek( nLen );
388 #endif
389 xSeek->seek(nLen);
390 Reference< XOutputStream> xOut = pHelper->getOutputStream();
391 OSL_ENSURE(xOut.is(),"No output stream!");
392
393 ::sal_Int64 diff = position - nLen;
394 sal_Int32 n;
395 while( diff != 0 )
396 {
397 if ( BUFFER_SIZE < diff )
398 {
399 n = static_cast<sal_Int32>(BUFFER_SIZE);
400 diff = diff - BUFFER_SIZE;
401 }
402 else
403 {
404 n = static_cast<sal_Int32>(diff);
405 diff = 0;
406 }
407 Sequence< ::sal_Int8 > aData(n);
408 memset(aData.getArray(),0,n);
409 xOut->writeBytes(aData);
410 #ifdef HSQLDB_DBG
411 aDataLog.write( aData.getConstArray(), n );
412 #endif
413 }
414 }
415 xSeek->seek(position);
416 OSL_ENSURE(xSeek->getPosition() == position,"Wrong position after seeking the stream");
417
418 #ifdef HSQLDB_DBG
419 aDataLog.seek( position );
420 OSL_ENSURE( xSeek->getPosition() == aDataLog.tell(), "Wrong position after seeking the stream" );
421 #endif
422 }
423 }
424 // -----------------------------------------------------------------------------
425
write_to_storage_stream_from_buffer(JNIEnv * env,jobject,jstring name,jstring key,jbyteArray buffer,jint off,jint len,DataLogFile * logger)426 void write_to_storage_stream_from_buffer( JNIEnv* env, jobject /*obj_this*/, jstring name, jstring key, jbyteArray buffer, jint off, jint len, DataLogFile* logger )
427 {
428 OSL_UNUSED( logger );
429 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
430 Reference< XOutputStream> xOut = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>();
431 OSL_ENSURE(xOut.is(),"Stream is NULL");
432
433 try
434 {
435 if ( xOut.is() )
436 {
437 jbyte *buf = env->GetByteArrayElements(buffer,NULL);
438 if (JNI_FALSE != env->ExceptionCheck())
439 {
440 env->ExceptionClear();
441 OSL_ENSURE(0,"ExceptionClear");
442 }
443 OSL_ENSURE(buf,"buf is NULL");
444 if ( buf && len > 0 && len <= env->GetArrayLength(buffer))
445 {
446 Sequence< ::sal_Int8 > aData(buf + off,len);
447 env->ReleaseByteArrayElements(buffer, buf, JNI_ABORT);
448 xOut->writeBytes(aData);
449 #ifdef HSQLDB_DBG
450 if ( logger )
451 logger->write( aData.getConstArray(), len );
452 #endif
453 }
454 }
455 else
456 {
457 ThrowException( env,
458 "java/io/IOException",
459 "No OutputStream");
460 }
461 }
462 catch(Exception& e)
463 {
464 OSL_ENSURE(0,"Exception caught! : write [BII)V");
465 StorageContainer::throwJavaException(e,env);
466 }
467 }
468
469 // -----------------------------------------------------------------------------
470
471 /*
472 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
473 * Method: write
474 * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)V
475 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_write(JNIEnv * env,jobject obj_this,jstring name,jstring key,jbyteArray buffer,jint off,jint len)476 SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_write
477 (JNIEnv * env, jobject obj_this,jstring name, jstring key, jbyteArray buffer, jint off, jint len)
478 {
479 #ifdef HSQLDB_DBG
480 OperationLogFile aOpLog( env, name, "data" );
481 aOpLog.logOperation( "write( byte[], int, int )" );
482
483 DataLogFile aDataLog( env, name, "data" );
484 write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog );
485 #else
486 write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len );
487 #endif
488 }
489 // -----------------------------------------------------------------------------
490
write_to_storage_stream(JNIEnv * env,jobject,jstring name,jstring key,jint v,DataLogFile * logger)491 void write_to_storage_stream( JNIEnv* env, jobject /*obj_this*/, jstring name, jstring key, jint v, DataLogFile* logger )
492 {
493 OSL_UNUSED( logger );
494
495 ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key);
496 Reference< XOutputStream> xOut = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>();
497 OSL_ENSURE(xOut.is(),"Stream is NULL");
498 try
499 {
500 if ( xOut.is() )
501 {
502 Sequence< ::sal_Int8 > oneByte(4);
503 oneByte[0] = (sal_Int8) ((v >> 24) & 0xFF);
504 oneByte[1] = (sal_Int8) ((v >> 16) & 0xFF);
505 oneByte[2] = (sal_Int8) ((v >> 8) & 0xFF);
506 oneByte[3] = (sal_Int8) ((v >> 0) & 0xFF);
507
508 xOut->writeBytes(oneByte);
509 #ifdef HSQLDB_DBG
510 if ( logger )
511 logger->write( oneByte.getConstArray(), 4 );
512 #endif
513 }
514 else
515 {
516 ThrowException( env,
517 "java/io/IOException",
518 "No OutputStream");
519 }
520 }
521 catch(Exception& e)
522 {
523 OSL_ENSURE(0,"Exception catched! : writeBytes(aData);");
524 StorageContainer::throwJavaException(e,env);
525 }
526 }
527
528 // -----------------------------------------------------------------------------
529
530 /*
531 * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess
532 * Method: writeInt
533 * Signature: (Ljava/lang/String;Ljava/lang/String;I)V
534 */
Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_writeInt(JNIEnv * env,jobject obj_this,jstring name,jstring key,jint v)535 SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_writeInt
536 (JNIEnv * env, jobject obj_this,jstring name, jstring key, jint v)
537 {
538 #ifdef HSQLDB_DBG
539 OperationLogFile aOpLog( env, name, "data" );
540 aOpLog.logOperation( "writeInt" );
541
542 DataLogFile aDataLog( env, name, "data" );
543 write_to_storage_stream( env, obj_this, name, key, v, &aDataLog );
544 #else
545 write_to_storage_stream( env, obj_this, name, key, v );
546 #endif
547 }
548