24#include <com/sun/star/beans/PropertyValue.hpp>
25#include <com/sun/star/uno/XComponentContext.hpp>
27#include <com/sun/star/io/XInputStream.hpp>
46#define M_ALT(CNT) (0x0200+(CNT))
49const sal_uInt16 pLotus[] =
50 { 0x0000, 0x0000, 0x0002, 0x0000,
51 M_ALT(2), 0x0004, 0x0006,
54const sal_uInt16 pLotusNew[] =
55 { 0x0000, 0x0000,
M_DC, 0x0000,
56 M_ALT(3), 0x0003, 0x0004, 0x0005,
57 0x0010, 0x0004, 0x0000, 0x0000,
60const sal_uInt16 pLotus2[] =
61 { 0x0000, 0x0000, 0x001A, 0x0000,
62 M_ALT(2), 0x0000, 0x0002,
67const sal_uInt16 pQPro[] =
68 { 0x0000, 0x0000, 0x0002, 0x0000,
69 M_ALT(4), 0x0001, 0x0002,
74const sal_uInt16 pDIF1[] =
76 'T',
'A',
'B',
'L',
'E',
83const sal_uInt16 pDIF2[] =
85 'T',
'A',
'B',
'L',
'E',
92const sal_uInt16 pSylk[] =
95 M_ALT(3),
'P',
'N',
'E',
98bool detectThisFormat(
SvStream& rStr,
const sal_uInt16* pSearch)
104 while( !rStr.
eof() && bSync )
106 sal_uInt16 nMuster = *pSearch;
108 if( nMuster < 0x0100 )
110 if(
static_cast<sal_uInt8>(nMuster) != nByte )
113 else if( nMuster &
M_DC )
116 else if( nMuster &
M_ALT(0) )
123 if(
static_cast<sal_uInt8>(*pSearch) == nByte )
128 else if( nMuster &
M_END )
160 rStream.
Seek(STREAM_SEEK_TO_BEGIN);
162 const size_t nBufSize = 2048;
163 sal_uInt16
aBuffer[ nBufSize ];
165 sal_uLong nBytesRead = rStream.Read( pByte, nBufSize*2);
167 if ( nBytesRead >= 2 && (aBuffer[0] == 0xfffe || aBuffer[0] == 0xfeff) )
174 sal_uInt16 nMask = 0xffff;
176 while( nBytesRead-- && nMask )
178 sal_uInt16 nVal = *
p++ & nMask;
179 if (!(nVal & 0x00ff))
181 if (!(nVal & 0xff00))
194 0x03, 0x04, 0x05, 0x30, 0x31, 0x43, 0xB3, 0x83, 0x8b, 0x8e, 0xf5 };
198 bool bValidMark =
false;
201 if (nValidMarks[
i] == nMark)
207 const size_t nHeaderBlockSize = 32;
209 const size_t nEmptyDbf = nHeaderBlockSize * 2 + 1;
211 sal_uInt64 nSize = rStream.
TellEnd();
212 if ( nSize < nEmptyDbf )
217 sal_uInt32 nRecords(0);
222 sal_uInt16 nHeaderLen;
226 sal_uInt16 nRecordSize(0);
229 if ( nHeaderLen < nEmptyDbf || nSize < nHeaderLen )
233 if (0 == nRecordSize)
239 nRecords = (nSize - nHeaderLen) / nRecordSize;
244 if (nSize < nHeaderLen + nRecords * sal_uInt64(nRecordSize))
253 sal_uInt16 nBlocks = (nHeaderLen - 1) / nHeaderBlockSize;
255 while ( nBlocks > 1 && nEndFlag != 0x0d ) {
256 rStream.
Seek( nBlocks-- * nHeaderBlockSize );
260 return ( 0x0d == nEndFlag );
266 OUString aTypeName = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_TYPENAME, OUString() );
267 uno::Reference< io::XInputStream >
xStream ( aMediaDesc[MediaDescriptor::PROP_INPUTSTREAM], uno::UNO_QUERY );
276 if ( !pStream || pStream->
GetError() )
280 const char* pSearchFilterName =
nullptr;
281 if (aTypeName ==
"calc_Lotus")
283 if (!detectThisFormat(*pStream, pLotus) && !detectThisFormat(*pStream, pLotusNew) && !detectThisFormat(*pStream, pLotus2))
286 pSearchFilterName =
"Lotus";
288 else if (aTypeName ==
"calc_QPro")
290 if (!detectThisFormat(*pStream, pQPro))
293 pSearchFilterName =
"Quattro Pro 6.0";
295 else if (aTypeName ==
"calc_SYLK")
297 if (!detectThisFormat(*pStream, pSylk))
300 pSearchFilterName =
"SYLK";
302 else if (aTypeName ==
"calc_DIF")
304 if (!detectThisFormat(*pStream, pDIF1) && !detectThisFormat(*pStream, pDIF2))
307 pSearchFilterName =
"DIF";
309 else if (aTypeName ==
"calc_dBase")
314 pSearchFilterName =
"dBase";
320 std::shared_ptr<const SfxFilter> pFilter = aMatcher.
GetFilter4FilterName(OUString::createFromAscii(pSearchFilterName));
325 aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= pFilter->GetName();
326 aMediaDesc >> lDescriptor;
332 return "com.sun.star.comp.calc.FormatDetector";
342 return {
"com.sun.star.frame.ExtendedTypeDetection" };
345extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
347 css::uno::Sequence<css::uno::Any>
const &)
constexpr OUStringLiteral sServiceName
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual OUString SAL_CALL detect(css::uno::Sequence< css::beans::PropertyValue > &lDescriptor) override
virtual ~ScFilterDetect() override
virtual sal_Bool SAL_CALL supportsService(const OUString &sServiceName) override
virtual OUString SAL_CALL getImplementationName() override
std::shared_ptr< const SfxFilter > GetFilter4FilterName(const OUString &rName, SfxFilterFlags nMust=SfxFilterFlags::NONE, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
void setStreamToLoadFrom(const css::uno::Reference< css::io::XInputStream > &xInputStream, bool bIsReadOnly)
void UseInteractionHandler(bool)
virtual sal_uInt64 TellEnd()
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
sal_uInt64 Seek(sal_uInt64 nPos)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
SvStream & ReadUChar(unsigned char &rChar)
#define SAL_N_ELEMENTS(arr)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_calc_FormatDetector_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
static bool lcl_MayBeDBase(SvStream &rStream)
#define STREAM_SEEK_TO_BEGIN
std::unique_ptr< char[]> aBuffer