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 */ 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 */ 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 */ 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 */ 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 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 */ 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 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 */ 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 */ 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 */ 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 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 */ 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 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 */ 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