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), hb(' '), numOfOLEChars(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