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