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 
10 #include <com/sun/star/document/XExtendedFilterDetection.hpp>
11 #include <com/sun/star/lang/XServiceInfo.hpp>
12 #include <com/sun/star/io/XInputStream.hpp>
13 #include <cppuhelper/implbase.hxx>
14 
15 #include <unotools/mediadescriptor.hxx>
16 
17 #include <rtl/strbuf.hxx>
18 
19 #include <orcus/format_detection.hpp>
20 
21 namespace com { namespace sun { namespace star { namespace uno { class XComponentContext; } } } }
22 
23 namespace {
24 
25 class OrcusFormatDetect : public ::cppu::WeakImplHelper<
26                           css::document::XExtendedFilterDetection,
27                           css::lang::XServiceInfo >
28 {
29 public:
30     explicit            OrcusFormatDetect();
31 
32     virtual OUString SAL_CALL getImplementationName() override;
33 
34     virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
35 
36     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
37 
38     virtual OUString SAL_CALL
39                         detect( css::uno::Sequence< css::beans::PropertyValue >& rMediaDescSeq ) override;
40 
41 private:
42 };
43 
OrcusFormatDetect()44 OrcusFormatDetect::OrcusFormatDetect()
45 {
46 }
47 
getImplementationName()48 OUString OrcusFormatDetect::getImplementationName()
49 {
50     return OUString();
51 }
52 
supportsService(const OUString &)53 sal_Bool OrcusFormatDetect::supportsService(const OUString& /*rServiceName*/)
54 {
55     return false;
56 }
57 
getSupportedServiceNames()58 css::uno::Sequence<OUString> OrcusFormatDetect::getSupportedServiceNames()
59 {
60     return css::uno::Sequence<OUString>();
61 }
62 
detect(css::uno::Sequence<css::beans::PropertyValue> & rMediaDescSeq)63 OUString OrcusFormatDetect::detect(css::uno::Sequence<css::beans::PropertyValue>& rMediaDescSeq)
64 {
65     utl::MediaDescriptor aMediaDescriptor( rMediaDescSeq );
66     bool bAborted = aMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ABORTED(), false);
67     if (bAborted)
68         return OUString();
69 
70     css::uno::Reference<css::io::XInputStream> xInputStream(aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM()], css::uno::UNO_QUERY );
71     OStringBuffer aContent(xInputStream->available());
72 
73     static const sal_Int32 nBytes = 4096;
74     css::uno::Sequence<sal_Int8> aSeq(nBytes);
75     bool bEnd = false;
76     while(!bEnd)
77     {
78         sal_Int32 nReadBytes = xInputStream->readBytes(aSeq, nBytes);
79         bEnd = (nReadBytes != nBytes);
80         aContent.append(reinterpret_cast<const char*>(aSeq.getConstArray()), nReadBytes);
81     }
82 
83     orcus::format_t eFormat = orcus::detect(reinterpret_cast<const unsigned char*>(aContent.getStr()), aContent.getLength());
84 
85     switch (eFormat)
86     {
87         case orcus::format_t::gnumeric:
88             return "Gnumeric XML";
89         case orcus::format_t::xls_xml:
90             return "calc_MS_Excel_2003_XML";
91         default:
92             ;
93     }
94 
95     return OUString();
96 }
97 
98 }
99 
100 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_sc_OrcusFormatDetect_get_implementation(css::uno::XComponentContext *,css::uno::Sequence<css::uno::Any> const &)101 com_sun_star_comp_sc_OrcusFormatDetect_get_implementation(css::uno::XComponentContext* ,
102                                                            css::uno::Sequence<css::uno::Any> const &)
103 {
104     return cppu::acquire(new OrcusFormatDetect());
105 }
106 
107 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
108