bump product version to 7.2.5.1
[LibreOffice.git] / connectivity / source / drivers / firebird / Clob.cxx
blob358451738003eeba4241986341d43920c29b1777
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <sal/config.h>
12 #include <string_view>
14 #include "Clob.hxx"
15 #include "Blob.hxx"
17 #include <connectivity/CommonTools.hxx>
18 #include <connectivity/dbexception.hxx>
20 using namespace ::connectivity::firebird;
22 using namespace ::osl;
24 using namespace ::com::sun::star;
25 using namespace ::com::sun::star::io;
26 using namespace ::com::sun::star::sdbc;
27 using namespace ::com::sun::star::uno;
29 Clob::Clob(isc_db_handle* pDatabaseHandle,
30 isc_tr_handle* pTransactionHandle,
31 ISC_QUAD const & aBlobID):
32 Clob_BASE(m_aMutex),
33 m_aBlob(new connectivity::firebird::Blob(pDatabaseHandle, pTransactionHandle, aBlobID)),
34 m_nCharCount(-1)
38 void SAL_CALL Clob::disposing()
40 m_aBlob->dispose();
41 m_aBlob.clear();
42 Clob_BASE::disposing();
45 sal_Int64 SAL_CALL Clob::length()
47 MutexGuard aGuard(m_aMutex);
48 checkDisposed(Clob_BASE::rBHelper.bDisposed);
50 if( m_nCharCount >= 0 )
51 return m_nCharCount;
52 m_nCharCount = 0;
54 // Read each segment, and calculate it's size by interpreting it as a
55 // character stream. Assume that no characters are split by the segments.
56 bool bLastSegmRead = false;
59 uno::Sequence < sal_Int8 > aSegmentBytes;
60 bLastSegmRead = m_aBlob->readOneSegment( aSegmentBytes );
61 OUString sSegment ( reinterpret_cast< char *>( aSegmentBytes.getArray() ),
62 aSegmentBytes.getLength(),
63 RTL_TEXTENCODING_UTF8 );
65 if( !bLastSegmRead)
66 m_nCharCount += sSegment.getLength();
67 }while( !bLastSegmRead );
69 m_aBlob->closeInput(); // reset position
70 return m_nCharCount;
73 OUString SAL_CALL Clob::getSubString(sal_Int64 nPosition,
74 sal_Int32 nLength)
76 MutexGuard aGuard(m_aMutex);
77 checkDisposed(Clob_BASE::rBHelper.bDisposed);
78 // TODO do not reset position if it is not necessary
79 m_aBlob->closeInput(); // reset position
81 OUStringBuffer sSegmentBuffer;
82 sal_Int64 nActPos = 1;
83 sal_Int32 nActLen = 0;
85 // skip irrelevant parts
86 while( nActPos < nPosition )
88 uno::Sequence < sal_Int8 > aSegmentBytes;
89 bool bLastRead = m_aBlob->readOneSegment( aSegmentBytes );
90 if( bLastRead )
91 throw lang::IllegalArgumentException("nPosition out of range", *this, 0);
93 OUString sSegment ( reinterpret_cast< char *>( aSegmentBytes.getArray() ),
94 aSegmentBytes.getLength(),
95 RTL_TEXTENCODING_UTF8 );
96 sal_Int32 nStrLen = sSegment.getLength();
97 nActPos += nStrLen;
98 if( nActPos > nPosition )
100 sal_Int32 nCharsToCopy = static_cast<sal_Int32>(nActPos - nPosition);
101 if( nCharsToCopy > nLength )
102 nCharsToCopy = nLength;
103 // append relevant part of first segment
104 sSegmentBuffer.append( sSegment.subView(0, nCharsToCopy) );
105 nActLen += sSegmentBuffer.getLength();
109 // read nLength characters
110 while( nActLen < nLength )
112 uno::Sequence < sal_Int8 > aSegmentBytes;
113 bool bLastRead = m_aBlob->readOneSegment( aSegmentBytes );
115 OUString sSegment ( reinterpret_cast< char *>( aSegmentBytes.getArray() ),
116 aSegmentBytes.getLength(),
117 RTL_TEXTENCODING_UTF8 );
118 sal_Int32 nStrLen = sSegment.getLength();
119 if( nActLen + nStrLen > nLength )
120 sSegmentBuffer.append(sSegment.subView(0, nLength - nActLen));
121 else
122 sSegmentBuffer.append(sSegment);
123 nActLen += nStrLen;
125 if( bLastRead && nActLen < nLength )
126 throw lang::IllegalArgumentException("out of range", *this, 0);
129 return sSegmentBuffer.makeStringAndClear();
132 uno::Reference< XInputStream > SAL_CALL Clob::getCharacterStream()
134 MutexGuard aGuard(m_aMutex);
135 checkDisposed(Clob_BASE::rBHelper.bDisposed);
137 return m_aBlob->getBinaryStream();
140 sal_Int64 SAL_CALL Clob::position(const OUString& /*rPattern*/,
141 sal_Int32 /*nStart*/)
143 ::dbtools::throwFeatureNotImplementedSQLException("Clob::position", *this);
144 return 0;
147 sal_Int64 SAL_CALL Clob::positionOfClob(const Reference <XClob >& /*rPattern*/,
148 sal_Int64 /*aStart*/)
150 ::dbtools::throwFeatureNotImplementedSQLException("Blob::positionOfBlob", *this);
151 return 0;
154 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */