2013-07-21 17:45:08 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Blob.hxx"
|
2013-07-31 16:03:29 +02:00
|
|
|
#include "Connection.hxx"
|
2013-07-25 16:30:32 +02:00
|
|
|
#include "Util.hxx"
|
2013-07-21 17:45:08 +02:00
|
|
|
|
|
|
|
#include "connectivity/dbexception.hxx"
|
|
|
|
|
|
|
|
using namespace ::connectivity::firebird;
|
|
|
|
|
|
|
|
using namespace ::cppu;
|
|
|
|
using namespace ::osl;
|
|
|
|
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
using namespace ::com::sun::star::io;
|
|
|
|
using namespace ::com::sun::star::sdbc;
|
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
|
|
|
|
Blob::Blob(isc_db_handle* pDatabaseHandle,
|
|
|
|
isc_tr_handle* pTransactionHandle,
|
|
|
|
ISC_QUAD& aBlobID):
|
|
|
|
Blob_BASE(m_aMutex),
|
|
|
|
m_pDatabaseHandle(pDatabaseHandle),
|
|
|
|
m_pTransactionHandle(pTransactionHandle),
|
|
|
|
m_blobID(aBlobID),
|
|
|
|
m_blobHandle(0),
|
|
|
|
m_bBlobOpened(false),
|
|
|
|
m_blobData(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Blob::ensureBlobIsOpened()
|
|
|
|
throw(SQLException)
|
|
|
|
{
|
|
|
|
MutexGuard aGuard(m_aMutex);
|
|
|
|
|
|
|
|
if (m_bBlobOpened)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ISC_STATUS aErr;
|
|
|
|
aErr = isc_open_blob2(m_statusVector,
|
|
|
|
m_pDatabaseHandle,
|
|
|
|
m_pTransactionHandle,
|
|
|
|
&m_blobHandle,
|
|
|
|
&m_blobID,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
if (aErr)
|
2013-07-25 16:30:32 +02:00
|
|
|
evaluateStatusVector(m_statusVector, "isc_open_blob2", *this);
|
2013-07-21 17:45:08 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL Blob::disposing(void)
|
|
|
|
{
|
|
|
|
MutexGuard aGuard(m_aMutex);
|
|
|
|
|
|
|
|
if (m_bBlobOpened)
|
|
|
|
{
|
|
|
|
ISC_STATUS aErr;
|
|
|
|
aErr = isc_close_blob(m_statusVector,
|
|
|
|
&m_blobHandle);
|
|
|
|
if (aErr)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2013-07-25 16:30:32 +02:00
|
|
|
evaluateStatusVector(m_statusVector, "isc_close_blob", *this);
|
2013-07-21 17:45:08 +02:00
|
|
|
}
|
|
|
|
catch (SQLException e)
|
|
|
|
{
|
|
|
|
// we cannot throw any exceptions here anyway
|
|
|
|
SAL_WARN("connectivity.firebird", "isc_close_blob failed\n" <<
|
|
|
|
e.Message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Blob_BASE::disposing();
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int64 SAL_CALL Blob::length()
|
|
|
|
throw(SQLException, RuntimeException)
|
|
|
|
{
|
|
|
|
MutexGuard aGuard(m_aMutex);
|
|
|
|
checkDisposed(Blob_BASE::rBHelper.bDisposed);
|
|
|
|
ensureBlobIsOpened();
|
|
|
|
|
|
|
|
char aBlobItems[] = {
|
|
|
|
isc_info_blob_total_length
|
|
|
|
};
|
|
|
|
char aResultBuffer[20];
|
|
|
|
|
|
|
|
isc_blob_info(m_statusVector,
|
|
|
|
&m_blobHandle,
|
|
|
|
sizeof(aBlobItems),
|
|
|
|
aBlobItems,
|
|
|
|
sizeof(aResultBuffer),
|
|
|
|
aResultBuffer);
|
2013-07-25 16:30:32 +02:00
|
|
|
|
|
|
|
evaluateStatusVector(m_statusVector, "isc_blob_info", *this);
|
2013-07-21 17:45:08 +02:00
|
|
|
if (*aResultBuffer == isc_info_blob_total_length)
|
|
|
|
{
|
|
|
|
short aResultLength = (short) isc_vax_integer(aResultBuffer, 2);
|
|
|
|
return isc_vax_integer(aResultBuffer+2, aResultLength);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uno::Sequence< sal_Int8 > SAL_CALL Blob::getBytes(sal_Int64 aPosition, sal_Int32 aLength)
|
|
|
|
throw(SQLException, RuntimeException)
|
|
|
|
{
|
|
|
|
MutexGuard aGuard(m_aMutex);
|
|
|
|
checkDisposed(Blob_BASE::rBHelper.bDisposed);
|
|
|
|
ensureBlobIsOpened();
|
|
|
|
|
|
|
|
sal_Int64 aTotalLength = length();
|
|
|
|
|
|
|
|
if (!(aPosition + aLength < aTotalLength))
|
|
|
|
{
|
|
|
|
throw SQLException("Byte array requested outwith valid range", *this, OUString(), 1, Any() );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aTotalLength != m_blobData.getLength())
|
|
|
|
{
|
|
|
|
m_blobData = uno::Sequence< sal_Int8 >(aTotalLength);
|
|
|
|
char* pArray = (char*) m_blobData.getArray();
|
|
|
|
sal_Int64 aBytesRead = 0;
|
|
|
|
|
|
|
|
unsigned short aLengthRead; // The amount read in in a isc_get_segment call
|
|
|
|
|
|
|
|
ISC_STATUS aErr;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
aErr = isc_get_segment(m_statusVector,
|
|
|
|
&m_blobHandle,
|
|
|
|
&aLengthRead,
|
|
|
|
aTotalLength - aBytesRead,
|
|
|
|
pArray + aBytesRead);
|
|
|
|
}
|
|
|
|
while (aErr == 0 || m_statusVector[1] == isc_segment);
|
|
|
|
// Denotes either sucessful read, or only part of segment read successfully.
|
|
|
|
if (aErr)
|
|
|
|
{
|
|
|
|
m_blobData = uno::Sequence< sal_Int8 >(0);
|
2013-07-25 16:30:32 +02:00
|
|
|
evaluateStatusVector(m_statusVector, "isc_get_segment", *this);
|
2013-07-21 17:45:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aLength<aTotalLength)
|
|
|
|
{
|
|
|
|
uno::Sequence< sal_Int8 > aRet(aLength);
|
|
|
|
memcpy(aRet.getArray(), m_blobData.getArray() + aLength, aLength);
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return m_blobData; // TODO: subsequence
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uno::Reference< XInputStream > SAL_CALL Blob::getBinaryStream()
|
|
|
|
throw(SQLException, RuntimeException)
|
|
|
|
{
|
|
|
|
// MutexGuard aGuard(m_aMutex);
|
|
|
|
// checkDisposed(Blob_BASE::rBHelper.bDisposed);
|
|
|
|
// ensureBlobIsOpened();
|
|
|
|
|
|
|
|
::dbtools::throwFeatureNotImplementedException("Blob::positionOfBlob", *this);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int64 SAL_CALL Blob::position(const uno::Sequence< sal_Int8 >& rPattern,
|
|
|
|
sal_Int64 aStart)
|
|
|
|
throw(SQLException, RuntimeException)
|
|
|
|
{
|
|
|
|
// MutexGuard aGuard(m_aMutex);
|
|
|
|
// checkDisposed(Blob_BASE::rBHelper.bDisposed);
|
|
|
|
// ensureBlobIsOpened();
|
|
|
|
|
|
|
|
(void) rPattern;
|
|
|
|
(void) aStart;
|
|
|
|
::dbtools::throwFeatureNotImplementedException("Blob::positionOfBlob", *this);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int64 SAL_CALL Blob::positionOfBlob(const uno::Reference< XBlob >& rPattern,
|
|
|
|
sal_Int64 aStart)
|
|
|
|
throw(SQLException, RuntimeException)
|
|
|
|
{
|
|
|
|
// MutexGuard aGuard(m_aMutex);
|
|
|
|
// checkDisposed(Blob_BASE::rBHelper.bDisposed);
|
|
|
|
// ensureBlobIsOpened();
|
|
|
|
|
|
|
|
(void) rPattern;
|
|
|
|
(void) aStart;
|
|
|
|
::dbtools::throwFeatureNotImplementedException("Blob::positionOfBlob", *this);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|