xref: /AOO41X/main/writerfilter/unocomponent/debugservices/rtftok/ScannerTestService.cxx (revision b4a4f18ca4dc88f864a44914739541fc69bd3f91)
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 #include "ScannerTestService.hxx"
25 #include <stdio.h>
26 #include <string.h>
27 #include <wchar.h>
28 #include <rtftok/RTFScanner.hxx>
29 #include <rtftok/RTFScannerHandler.hxx>
30 #include <com/sun/star/io/XStream.hpp>
31 #include <com/sun/star/io/XInputStream.hpp>
32 #include <com/sun/star/io/XSeekable.hpp>
33 #include <com/sun/star/io/XTruncate.hpp>
34 #include <com/sun/star/task/XStatusIndicator.hpp>
35 #include <com/sun/star/container/XNameContainer.hpp>
36 #include <ucbhelper/contentbroker.hxx>
37 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
38 #include <osl/process.h>
39 #include <rtl/string.hxx>
40 #include <hash_set>
41 #include <assert.h>
42 #include <cppuhelper/implbase2.hxx>
43 #include <com/sun/star/embed/XTransactedObject.hpp>
44 #include <com/sun/star/embed/XStorage.hpp>
45 #include <com/sun/star/util/XCloseable.hpp>
46 #include <comphelper/storagehelper.hxx>
47 #include <com/sun/star/embed/XTransactedObject.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <comphelper/seqstream.hxx>
51 
52 #include <ctype.h>
53 
54 using namespace ::com::sun::star;
55 
56 namespace writerfilter { namespace rtftok {
57 
58 const sal_Char ScannerTestService::SERVICE_NAME[40] = "debugservices.rtftok.ScannerTestService";
59 const sal_Char ScannerTestService::IMPLEMENTATION_NAME[40] = "debugservices.rtftok.ScannerTestService";
60 
61 struct ScannerTestServiceHelper
62 {
operator ()writerfilter::rtftok::ScannerTestServiceHelper63     size_t operator()(const rtl::OString &str) const
64     {
65         return str.hashCode();
66     }
operator ()writerfilter::rtftok::ScannerTestServiceHelper67     bool operator()(const rtl::OString &str1, const rtl::OString &str2) const
68     {
69         return str1.compareTo(str2)==0;
70     }
71 };
72 
73 typedef ::std::hash_set< ::rtl::OString, ScannerTestServiceHelper, ScannerTestServiceHelper > ScannerTestServiceTokenMap;
74 
75 class MyRtfScannerHandler : public writerfilter::rtftok::RTFScannerHandler
76 {
77     ScannerTestServiceTokenMap destMap;
78     ScannerTestServiceTokenMap ctrlMap;
79     std::vector<unsigned char> binBuffer;
80     int objDataLevel;
81     int numOfOLEs;
82     unsigned char hb;
83     int numOfOLEChars;
84     uno::Reference<lang::XMultiServiceFactory> xServiceFactory;
85     uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess;
86     uno::Reference<embed::XStorage> xStorage;
87 
dest(char * token,char *)88     void dest(char* token, char* /*value*/)
89     {
90         destMap.insert(rtl::OString(token));
91 //      printf("{\\*\\%s%s ", token, value);
92         if (strcmp(token, "objdata")==0)
93         {
94             binBuffer.clear();
95             objDataLevel=1;
96             numOfOLEChars=0;
97         }
98     }
ctrl(char * token,char *)99     void ctrl(char*token, char* /*value*/)
100     {
101         ctrlMap.insert(rtl::OString(token));
102 //      printf("\\%s%s ", token, value);
103     }
lbrace(void)104     void lbrace(void)
105     {
106 //      printf("{");
107     }
rbrace(void)108     void rbrace(void)
109     {
110 #ifndef LINUX
111         unsigned char * binBufferStr = ((unsigned char*)&(*binBuffer.begin()));
112 
113         if (objDataLevel)
114         {
115             int o=0;
116             unsigned int type=((unsigned int)binBuffer[o]) | ((unsigned int)binBuffer[o+1])<<8 | ((unsigned int)binBuffer[o+2])<<16 | ((unsigned int)binBuffer[o+3]<<24); o+=4;
117             unsigned int recType=((unsigned int)binBuffer[o]) | ((unsigned int)binBuffer[o+1])<<8 | ((unsigned int)binBuffer[o+2])<<16 | ((unsigned int)binBuffer[o+3]<<24); o+=4;
118             unsigned int strLen=((unsigned int)binBuffer[o]) | ((unsigned int)binBuffer[o+1])<<8 | ((unsigned int)binBuffer[o+2])<<16 | ((unsigned int)binBuffer[o+3]<<24); o+=4;
119             unsigned char *str=binBufferStr+o;
120             o+=strLen;
121             o+=4; // dummy1
122             o+=4; // dummy2
123             unsigned int binLen=((unsigned int)binBuffer[o]) | ((unsigned int)binBuffer[o+1])<<8 | ((unsigned int)binBuffer[o+2])<<16 | ((unsigned int)binBuffer[o+3]<<24); o+=4;
124             printf("OLE%i \"%s\" type=%i recType=%i binBuffer.size()=%u len=%u\n", numOfOLEs, str, type, recType, (unsigned int)(binBuffer.size()), o+binLen);
125             //assert(binBuffer.size()==o+binLen);
126             char buf[100];
127             sprintf(buf, "ole%02i.ole", numOfOLEs);
128 /*          if 0{
129             FILE *f=fopen(buf, "w+b");
130             unsigned char *data=binBuffer.begin();
131             fwrite(data+o, 1, binLen, f);
132             fclose(f);
133             }*/
134 /*
135             rtl_uString *dir=NULL;
136             osl_getProcessWorkingDir(&dir);
137             rtl::OUString absFileUrl;
138             rtl::OUString fileUrl=rtl::OUString::createFromAscii(buf);
139             osl_getAbsoluteFileURL(dir, fileUrl.pData, &absFileUrl.pData);
140             rtl_uString_release(dir);
141 */
142                 comphelper::ByteSequence seq(binLen);
143                 unsigned char *data0=binBufferStr;
144                 memcpy(seq.getArray(), data0+o, binLen);
145                 uno::Reference<io::XInputStream> myStream=new comphelper::SequenceInputStream(seq);
146 //          uno::Reference<io::XStream> myStream=xFileAccess->openFileReadWrite(absFileUrl);
147 //          uno::Reference<io::XStream> myStream(new MyStreamImpl(binBuffer, o));
148             uno::Sequence< uno::Any > aArgs0( 1 );
149             aArgs0[0] <<= myStream;
150             uno::Reference< container::XNameContainer > xNameContainer(
151             xServiceFactory->createInstanceWithArguments(
152                     ::rtl::OUString::createFromAscii("com.sun.star.embed.OLESimpleStorage" ),
153                     aArgs0 ),
154             uno::UNO_QUERY_THROW );
155             try {
156                 printf("TRY\n");
157         ::com::sun::star::uno::Sequence< ::rtl::OUString > names=xNameContainer->getElementNames();
158                 printf("OK\n");
159 
160             for(int i=0;i<names.getLength();i++)
161             {
162                 rtl::OUString &name=names[i];
163                 wprintf(L"name=%s\n", name.getStr());
164             }
165             {
166                 uno::Reference< io::XStream > xContentStream = xStorage->openStreamElement(
167                     rtl::OUString::createFromAscii(buf), embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
168                 uno::Reference<beans::XPropertySet> xContentStreamPropSet(xContentStream, uno::UNO_QUERY_THROW);
169                 xContentStreamPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.sun.star.oleobject")));
170                 uno::Reference<io::XOutputStream> myOutStream=xContentStream->getOutputStream();
171                 uno::Sequence< ::sal_Int8 > seq1(binLen);
172                 unsigned char *data1=binBufferStr;
173                 memcpy(seq1.getArray(), data1+o, binLen);
174                 myOutStream->writeBytes(seq1);
175                 myOutStream->closeOutput();
176             }
177 
178             } catch(com::sun::star::uno::RuntimeException &)
179             {
180                 printf("NOT OK\n");
181                 comphelper::ByteSequence seq2(4+binLen);
182                 //              memcpy(seq2.getArray(), &binLen, 4); assert(0); //TODO linux
183                 seq2[0]= sal::static_int_cast<sal_Int8>(binLen&0xFF);
184                 seq2[1]= sal::static_int_cast<sal_Int8>((binLen>>8)&0xFF);
185                 seq2[2]= sal::static_int_cast<sal_Int8>((binLen>>16)&0xFF);
186                 seq2[3]= sal::static_int_cast<sal_Int8>((binLen>>24)&0xFF);
187                 unsigned char *data2=binBufferStr;
188                 memcpy(seq2.getArray()+4, data2+o, binLen);
189                 uno::Reference<io::XInputStream> myInStream=new comphelper::SequenceInputStream(seq2);
190                 printf("SEQ OK\n");
191 
192                 uno::Reference< io::XStream > xContentStream = xStorage->openStreamElement(
193                     rtl::OUString::createFromAscii(buf), embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
194                 uno::Reference<beans::XPropertySet> xContentStreamPropSet(xContentStream, uno::UNO_QUERY_THROW);
195                 xContentStreamPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.sun.star.oleobject")));
196                 printf("CONTENT STREAM OK\n");
197 
198                 uno::Sequence< uno::Any > aArgs1( 1 );
199                 aArgs1[0] <<= xContentStream;
200                 uno::Reference< container::XNameContainer > xNameContainer2(
201                     xServiceFactory->createInstanceWithArguments(
202                     ::rtl::OUString::createFromAscii("com.sun.star.embed.OLESimpleStorage" ),
203                     aArgs1 ),
204                     uno::UNO_QUERY_THROW );
205                 printf("OLE STORAGE OK\n");
206 
207                 uno::Any anyStream;
208                 anyStream <<= myInStream;
209                 xNameContainer2->insertByName(rtl::OUString::createFromAscii("\1Ole10Native"), anyStream);
210                 printf("INSERT OK\n");
211 
212                 uno::Reference<embed::XTransactedObject> xTransact(xNameContainer2, uno::UNO_QUERY);
213                 xTransact->commit();
214             }
215             objDataLevel--;
216             numOfOLEs++;
217         }
218 #endif
219 //      printf("}");
220     }
addSpaces(int)221     void addSpaces(int /*count*/)
222     {
223 //      for(int i=0;i<count;i++)
224 //          printf(" ");
225 
226     }
addBinData(unsigned char)227     void addBinData(unsigned char /*data*/)
228     {
229 //      printf("%02Xh", data);
230     }
addChar(char ch)231     void addChar(char ch)
232     {
233 //      printf("%c", ch);
234         if (objDataLevel)
235         {
236             if (numOfOLEChars%2==0)
237             {
238                 char c=sal::static_int_cast<char>(toupper(ch));
239                 assert((c<='F' && c>='A') || (c<='9' && c>='0'));
240                 if(c>='A') hb=(unsigned char)(c-'A'+10); else hb=(unsigned char)(c-'0');
241             }
242             else
243             {
244                 unsigned char lb;
245                 char c=sal::static_int_cast<char>(toupper(ch));
246                 assert((c<='F' && c>='A') || (c<='9' && c>='0'));
247                 if(c>='A') lb=(unsigned char)(c-'A'+10); else lb=(unsigned char)(c-'0');
248                 unsigned char r=(hb<<4)|lb;
249                 binBuffer.push_back(r);
250             }
251             numOfOLEChars++;
252         }
253     }
addCharU(sal_Unicode)254     void addCharU(sal_Unicode /*ch*/)
255     {
256 //      printf("\\u%i ", ch);
257     }
addHexChar(char *)258     void addHexChar(char* /*hexch*/)
259     {
260 //      printf("\'%s ", hexch);
261     }
262 
263 
264 public:
MyRtfScannerHandler(uno::Reference<lang::XMultiServiceFactory> & xServiceFactory_,uno::Reference<com::sun::star::ucb::XSimpleFileAccess> & xFileAccess_,uno::Reference<embed::XStorage> & xStorage_)265     MyRtfScannerHandler(uno::Reference<lang::XMultiServiceFactory> &xServiceFactory_, uno::Reference<com::sun::star::ucb::XSimpleFileAccess> &xFileAccess_, uno::Reference<embed::XStorage> &xStorage_) :
266     objDataLevel(0), numOfOLEs(0),
267     xServiceFactory(xServiceFactory_),
268     xFileAccess(xFileAccess_),
269     xStorage(xStorage_)
270     {
271     }
272 
~MyRtfScannerHandler()273     virtual ~MyRtfScannerHandler() {}
274 
dump()275     void dump()
276     {
277         printf("Destinations:\n");
278         for(ScannerTestServiceTokenMap::iterator i=destMap.begin();i!=destMap.end();i++)
279         {
280             printf("  %s\n", i->getStr());
281         }
282         printf("Ctrls:\n");
283         for(ScannerTestServiceTokenMap::iterator i=ctrlMap.begin();i!=ctrlMap.end();i++)
284         {
285             printf("  %s\n", i->getStr());
286         }
287     }
288 };
289 
290 class RtfInputSourceImpl : public rtftok::RTFInputSource
291 {
292 private:
293     uno::Reference< io::XInputStream > xInputStream;
294     uno::Reference< io::XSeekable > xSeekable;
295     uno::Reference< task::XStatusIndicator > xStatusIndicator;
296     sal_Int64 bytesTotal;
297     sal_Int64 bytesRead;
298 public:
RtfInputSourceImpl(uno::Reference<io::XInputStream> & xInputStream_,uno::Reference<task::XStatusIndicator> & xStatusIndicator_)299     RtfInputSourceImpl(uno::Reference< io::XInputStream > &xInputStream_, uno::Reference< task::XStatusIndicator > &xStatusIndicator_) :
300       xInputStream(xInputStream_),
301       xStatusIndicator(xStatusIndicator_),
302       bytesRead(0)
303     {
304         xSeekable=uno::Reference< io::XSeekable >(xInputStream, uno::UNO_QUERY);
305         if (xSeekable.is())
306             bytesTotal=xSeekable->getLength();
307         if (xStatusIndicator.is() && xSeekable.is())
308         {
309             xStatusIndicator->start(::rtl::OUString::createFromAscii("Converting"), 100);
310         }
311     }
312 
~RtfInputSourceImpl()313     virtual ~RtfInputSourceImpl() {}
314 
read(void * buf,int maxlen)315     int read(void *buf, int maxlen)
316     {
317         uno::Sequence< sal_Int8 > buffer;
318         int len=xInputStream->readSomeBytes(buffer,maxlen);
319         if (len>0)
320         {
321             sal_Int8 *_buffer=buffer.getArray();
322             memcpy(buf, _buffer, len);
323             bytesRead+=len;
324             if (xStatusIndicator.is())
325             {
326                 if (xSeekable.is())
327                 {
328                     xStatusIndicator->setValue((int)(bytesRead*100/bytesTotal));
329                 }
330                 else
331                 {
332                     char buf1[100];
333                     sprintf(buf1, "Converted %" SAL_PRIdINT64 " KB", bytesRead/1024);
334                     xStatusIndicator->start(::rtl::OUString::createFromAscii(buf1), 0);
335                 }
336             }
337             return len;
338         }
339         else
340         {
341             if (xStatusIndicator.is())
342             {
343                 xStatusIndicator->end();
344             }
345             return 0;
346         }
347     }
348 };
349 
ScannerTestService(const uno::Reference<uno::XComponentContext> & xContext_)350 ScannerTestService::ScannerTestService(const uno::Reference< uno::XComponentContext > &xContext_) :
351 xContext( xContext_ )
352 {
353 }
354 
run(const uno::Sequence<rtl::OUString> & aArguments)355 sal_Int32 SAL_CALL ScannerTestService::run( const uno::Sequence< rtl::OUString >& aArguments ) throw (uno::RuntimeException)
356 {
357 
358   printf("TEST\n");
359 
360     uno::Sequence<uno::Any> aUcbInitSequence(2);
361     aUcbInitSequence[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
362     aUcbInitSequence[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
363     uno::Reference<lang::XMultiServiceFactory> xServiceFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW);
364   printf("A\n");
365     uno::Reference<lang::XMultiComponentFactory> xFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW );
366   printf("B\n");
367     if (::ucbhelper::ContentBroker::initialize(xServiceFactory, aUcbInitSequence))
368     {
369   printf("C\n");
370             rtl::OUString arg=aArguments[0];
371 
372             uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess(
373             xFactory->createInstanceWithContext(
374                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")),
375                 xContext), uno::UNO_QUERY_THROW );
376 
377             rtl_uString *dir=NULL;
378             osl_getProcessWorkingDir(&dir);
379             rtl::OUString absFileUrl;
380             osl_getAbsoluteFileURL(dir, arg.pData, &absFileUrl.pData);
381             rtl_uString_release(dir);
382 
383             uno::Reference <lang::XSingleServiceFactory> xStorageFactory(
384                 xServiceFactory->createInstance (rtl::OUString::createFromAscii("com.sun.star.embed.StorageFactory")), uno::UNO_QUERY_THROW);
385 
386             rtl::OUString outFileUrl;
387             {
388             rtl_uString *dir1=NULL;
389             osl_getProcessWorkingDir(&dir1);
390             osl_getAbsoluteFileURL(dir1, aArguments[1].pData, &outFileUrl.pData);
391             rtl_uString_release(dir1);
392             }
393 
394             uno::Sequence< uno::Any > aArgs2( 2 );
395             aArgs2[0] <<= outFileUrl;
396             aArgs2[1] <<= embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE;
397             uno::Reference<embed::XStorage> xStorage(xStorageFactory->createInstanceWithArguments(aArgs2), uno::UNO_QUERY_THROW);
398             uno::Reference<beans::XPropertySet> xPropSet(xStorage, uno::UNO_QUERY_THROW);
399             xPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.oasis.opendocument.text")));
400             uno::Reference<io::XInputStream> xInputStream = xFileAccess->openFileRead(absFileUrl);
401             uno::Reference< task::XStatusIndicator > xStatusIndicator;
402 
403         TimeValue t1; osl_getSystemTime(&t1);
404 
405             RtfInputSourceImpl rtfInputSource(xInputStream, xStatusIndicator);
406             MyRtfScannerHandler eventHandler(xServiceFactory, xFileAccess, xStorage);
407             writerfilter::rtftok::RTFScanner *rtfScanner=writerfilter::rtftok::RTFScanner::createRTFScanner(rtfInputSource, eventHandler);
408 
409             rtfScanner->yylex();
410             delete rtfScanner;
411 
412         TimeValue t2; osl_getSystemTime(&t2);
413         printf("time=%" SAL_PRIuUINT32 "s\n", t2.Seconds-t1.Seconds);
414 
415 //          eventHandler.dump();
416             uno::Reference<embed::XTransactedObject> xTransact(xStorage, uno::UNO_QUERY);
417             xTransact->commit();
418 
419 
420         ::ucbhelper::ContentBroker::deinitialize();
421     }
422     else
423     {
424         fprintf(stderr, "can't initialize UCB");
425     }
426     return 0;
427 }
428 
ScannerTestService_getImplementationName()429 ::rtl::OUString ScannerTestService_getImplementationName ()
430 {
431     return rtl::OUString::createFromAscii ( ScannerTestService::IMPLEMENTATION_NAME );
432 }
433 
ScannerTestService_supportsService(const::rtl::OUString & ServiceName)434 sal_Bool SAL_CALL ScannerTestService_supportsService( const ::rtl::OUString& ServiceName )
435 {
436     return ServiceName.equals( rtl::OUString::createFromAscii( ScannerTestService::SERVICE_NAME ) );
437 }
ScannerTestService_getSupportedServiceNames()438 uno::Sequence< rtl::OUString > SAL_CALL ScannerTestService_getSupportedServiceNames(  ) throw (uno::RuntimeException)
439 {
440     uno::Sequence < rtl::OUString > aRet(1);
441     rtl::OUString* pArray = aRet.getArray();
442     pArray[0] =  rtl::OUString::createFromAscii ( ScannerTestService::SERVICE_NAME );
443     return aRet;
444 }
445 
ScannerTestService_createInstance(const uno::Reference<uno::XComponentContext> & xContext)446 uno::Reference< uno::XInterface > SAL_CALL ScannerTestService_createInstance( const uno::Reference< uno::XComponentContext > & xContext) throw( uno::Exception )
447 {
448     return (cppu::OWeakObject*) new ScannerTestService( xContext );
449 }
450 
451 } } /* end namespace writerfilter::rtftok */
452