| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "ScannerTestService.hxx" |
| #include <stdio.h> |
| #include <string.h> |
| #include <wchar.h> |
| #include <rtftok/RTFScanner.hxx> |
| #include <rtftok/RTFScannerHandler.hxx> |
| #include <com/sun/star/io/XStream.hpp> |
| #include <com/sun/star/io/XInputStream.hpp> |
| #include <com/sun/star/io/XSeekable.hpp> |
| #include <com/sun/star/io/XTruncate.hpp> |
| #include <com/sun/star/task/XStatusIndicator.hpp> |
| #include <com/sun/star/container/XNameContainer.hpp> |
| #include <ucbhelper/contentbroker.hxx> |
| #include <com/sun/star/ucb/XSimpleFileAccess.hpp> |
| #include <osl/process.h> |
| #include <rtl/string.hxx> |
| #include <hash_set> |
| #include <assert.h> |
| #include <cppuhelper/implbase2.hxx> |
| #include <com/sun/star/embed/XTransactedObject.hpp> |
| #include <com/sun/star/embed/XStorage.hpp> |
| #include <com/sun/star/util/XCloseable.hpp> |
| #include <comphelper/storagehelper.hxx> |
| #include <com/sun/star/embed/XTransactedObject.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <comphelper/seqstream.hxx> |
| |
| #include <ctype.h> |
| |
| using namespace ::com::sun::star; |
| |
| namespace writerfilter { namespace rtftok { |
| |
| const sal_Char ScannerTestService::SERVICE_NAME[40] = "debugservices.rtftok.ScannerTestService"; |
| const sal_Char ScannerTestService::IMPLEMENTATION_NAME[40] = "debugservices.rtftok.ScannerTestService"; |
| |
| struct ScannerTestServiceHelper |
| { |
| size_t operator()(const rtl::OString &str) const |
| { |
| return str.hashCode(); |
| } |
| bool operator()(const rtl::OString &str1, const rtl::OString &str2) const |
| { |
| return str1.compareTo(str2)==0; |
| } |
| }; |
| |
| typedef ::std::hash_set< ::rtl::OString, ScannerTestServiceHelper, ScannerTestServiceHelper > ScannerTestServiceTokenMap; |
| |
| class MyRtfScannerHandler : public writerfilter::rtftok::RTFScannerHandler |
| { |
| ScannerTestServiceTokenMap destMap; |
| ScannerTestServiceTokenMap ctrlMap; |
| std::vector<unsigned char> binBuffer; |
| int objDataLevel; |
| int numOfOLEs; |
| unsigned char hb; |
| int numOfOLEChars; |
| uno::Reference<lang::XMultiServiceFactory> xServiceFactory; |
| uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess; |
| uno::Reference<embed::XStorage> xStorage; |
| |
| void dest(char* token, char* /*value*/) |
| { |
| destMap.insert(rtl::OString(token)); |
| // printf("{\\*\\%s%s ", token, value); |
| if (strcmp(token, "objdata")==0) |
| { |
| binBuffer.clear(); |
| objDataLevel=1; |
| numOfOLEChars=0; |
| } |
| } |
| void ctrl(char*token, char* /*value*/) |
| { |
| ctrlMap.insert(rtl::OString(token)); |
| // printf("\\%s%s ", token, value); |
| } |
| void lbrace(void) |
| { |
| // printf("{"); |
| } |
| void rbrace(void) |
| { |
| #ifndef LINUX |
| unsigned char * binBufferStr = ((unsigned char*)&(*binBuffer.begin())); |
| |
| if (objDataLevel) |
| { |
| int o=0; |
| 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; |
| 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; |
| 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; |
| unsigned char *str=binBufferStr+o; |
| o+=strLen; |
| o+=4; // dummy1 |
| o+=4; // dummy2 |
| 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; |
| printf("OLE%i \"%s\" type=%i recType=%i binBuffer.size()=%u len=%u\n", numOfOLEs, str, type, recType, (unsigned int)(binBuffer.size()), o+binLen); |
| //assert(binBuffer.size()==o+binLen); |
| char buf[100]; |
| sprintf(buf, "ole%02i.ole", numOfOLEs); |
| /* if 0{ |
| FILE *f=fopen(buf, "w+b"); |
| unsigned char *data=binBuffer.begin(); |
| fwrite(data+o, 1, binLen, f); |
| fclose(f); |
| }*/ |
| /* |
| rtl_uString *dir=NULL; |
| osl_getProcessWorkingDir(&dir); |
| rtl::OUString absFileUrl; |
| rtl::OUString fileUrl=rtl::OUString::createFromAscii(buf); |
| osl_getAbsoluteFileURL(dir, fileUrl.pData, &absFileUrl.pData); |
| rtl_uString_release(dir); |
| */ |
| comphelper::ByteSequence seq(binLen); |
| unsigned char *data0=binBufferStr; |
| memcpy(seq.getArray(), data0+o, binLen); |
| uno::Reference<io::XInputStream> myStream=new comphelper::SequenceInputStream(seq); |
| // uno::Reference<io::XStream> myStream=xFileAccess->openFileReadWrite(absFileUrl); |
| // uno::Reference<io::XStream> myStream(new MyStreamImpl(binBuffer, o)); |
| uno::Sequence< uno::Any > aArgs0( 1 ); |
| aArgs0[0] <<= myStream; |
| uno::Reference< container::XNameContainer > xNameContainer( |
| xServiceFactory->createInstanceWithArguments( |
| ::rtl::OUString::createFromAscii("com.sun.star.embed.OLESimpleStorage" ), |
| aArgs0 ), |
| uno::UNO_QUERY_THROW ); |
| try { |
| printf("TRY\n"); |
| ::com::sun::star::uno::Sequence< ::rtl::OUString > names=xNameContainer->getElementNames(); |
| printf("OK\n"); |
| |
| for(int i=0;i<names.getLength();i++) |
| { |
| rtl::OUString &name=names[i]; |
| wprintf(L"name=%s\n", name.getStr()); |
| } |
| { |
| uno::Reference< io::XStream > xContentStream = xStorage->openStreamElement( |
| rtl::OUString::createFromAscii(buf), embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); |
| uno::Reference<beans::XPropertySet> xContentStreamPropSet(xContentStream, uno::UNO_QUERY_THROW); |
| xContentStreamPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.sun.star.oleobject"))); |
| uno::Reference<io::XOutputStream> myOutStream=xContentStream->getOutputStream(); |
| uno::Sequence< ::sal_Int8 > seq1(binLen); |
| unsigned char *data1=binBufferStr; |
| memcpy(seq1.getArray(), data1+o, binLen); |
| myOutStream->writeBytes(seq1); |
| myOutStream->closeOutput(); |
| } |
| |
| } catch(com::sun::star::uno::RuntimeException &) |
| { |
| printf("NOT OK\n"); |
| comphelper::ByteSequence seq2(4+binLen); |
| // memcpy(seq2.getArray(), &binLen, 4); assert(0); //TODO linux |
| seq2[0]= sal::static_int_cast<sal_Int8>(binLen&0xFF); |
| seq2[1]= sal::static_int_cast<sal_Int8>((binLen>>8)&0xFF); |
| seq2[2]= sal::static_int_cast<sal_Int8>((binLen>>16)&0xFF); |
| seq2[3]= sal::static_int_cast<sal_Int8>((binLen>>24)&0xFF); |
| unsigned char *data2=binBufferStr; |
| memcpy(seq2.getArray()+4, data2+o, binLen); |
| uno::Reference<io::XInputStream> myInStream=new comphelper::SequenceInputStream(seq2); |
| printf("SEQ OK\n"); |
| |
| uno::Reference< io::XStream > xContentStream = xStorage->openStreamElement( |
| rtl::OUString::createFromAscii(buf), embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); |
| uno::Reference<beans::XPropertySet> xContentStreamPropSet(xContentStream, uno::UNO_QUERY_THROW); |
| xContentStreamPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.sun.star.oleobject"))); |
| printf("CONTENT STREAM OK\n"); |
| |
| uno::Sequence< uno::Any > aArgs1( 1 ); |
| aArgs1[0] <<= xContentStream; |
| uno::Reference< container::XNameContainer > xNameContainer2( |
| xServiceFactory->createInstanceWithArguments( |
| ::rtl::OUString::createFromAscii("com.sun.star.embed.OLESimpleStorage" ), |
| aArgs1 ), |
| uno::UNO_QUERY_THROW ); |
| printf("OLE STORAGE OK\n"); |
| |
| uno::Any anyStream; |
| anyStream <<= myInStream; |
| xNameContainer2->insertByName(rtl::OUString::createFromAscii("\1Ole10Native"), anyStream); |
| printf("INSERT OK\n"); |
| |
| uno::Reference<embed::XTransactedObject> xTransact(xNameContainer2, uno::UNO_QUERY); |
| xTransact->commit(); |
| } |
| objDataLevel--; |
| numOfOLEs++; |
| } |
| #endif |
| // printf("}"); |
| } |
| void addSpaces(int /*count*/) |
| { |
| // for(int i=0;i<count;i++) |
| // printf(" "); |
| |
| } |
| void addBinData(unsigned char /*data*/) |
| { |
| // printf("%02Xh", data); |
| } |
| void addChar(char ch) |
| { |
| // printf("%c", ch); |
| if (objDataLevel) |
| { |
| if (numOfOLEChars%2==0) |
| { |
| char c=sal::static_int_cast<char>(toupper(ch)); |
| assert((c<='F' && c>='A') || (c<='9' && c>='0')); |
| if(c>='A') hb=(unsigned char)(c-'A'+10); else hb=(unsigned char)(c-'0'); |
| } |
| else |
| { |
| unsigned char lb; |
| char c=sal::static_int_cast<char>(toupper(ch)); |
| assert((c<='F' && c>='A') || (c<='9' && c>='0')); |
| if(c>='A') lb=(unsigned char)(c-'A'+10); else lb=(unsigned char)(c-'0'); |
| unsigned char r=(hb<<4)|lb; |
| binBuffer.push_back(r); |
| } |
| numOfOLEChars++; |
| } |
| } |
| void addCharU(sal_Unicode /*ch*/) |
| { |
| // printf("\\u%i ", ch); |
| } |
| void addHexChar(char* /*hexch*/) |
| { |
| // printf("\'%s ", hexch); |
| } |
| |
| |
| public: |
| MyRtfScannerHandler(uno::Reference<lang::XMultiServiceFactory> &xServiceFactory_, uno::Reference<com::sun::star::ucb::XSimpleFileAccess> &xFileAccess_, uno::Reference<embed::XStorage> &xStorage_) : |
| objDataLevel(0), numOfOLEs(0), |
| xServiceFactory(xServiceFactory_), |
| xFileAccess(xFileAccess_), |
| xStorage(xStorage_) |
| { |
| } |
| |
| virtual ~MyRtfScannerHandler() {} |
| |
| void dump() |
| { |
| printf("Destinations:\n"); |
| for(ScannerTestServiceTokenMap::iterator i=destMap.begin();i!=destMap.end();i++) |
| { |
| printf(" %s\n", i->getStr()); |
| } |
| printf("Ctrls:\n"); |
| for(ScannerTestServiceTokenMap::iterator i=ctrlMap.begin();i!=ctrlMap.end();i++) |
| { |
| printf(" %s\n", i->getStr()); |
| } |
| } |
| }; |
| |
| class RtfInputSourceImpl : public rtftok::RTFInputSource |
| { |
| private: |
| uno::Reference< io::XInputStream > xInputStream; |
| uno::Reference< io::XSeekable > xSeekable; |
| uno::Reference< task::XStatusIndicator > xStatusIndicator; |
| sal_Int64 bytesTotal; |
| sal_Int64 bytesRead; |
| public: |
| RtfInputSourceImpl(uno::Reference< io::XInputStream > &xInputStream_, uno::Reference< task::XStatusIndicator > &xStatusIndicator_) : |
| xInputStream(xInputStream_), |
| xStatusIndicator(xStatusIndicator_), |
| bytesRead(0) |
| { |
| xSeekable=uno::Reference< io::XSeekable >(xInputStream, uno::UNO_QUERY); |
| if (xSeekable.is()) |
| bytesTotal=xSeekable->getLength(); |
| if (xStatusIndicator.is() && xSeekable.is()) |
| { |
| xStatusIndicator->start(::rtl::OUString::createFromAscii("Converting"), 100); |
| } |
| } |
| |
| virtual ~RtfInputSourceImpl() {} |
| |
| int read(void *buf, int maxlen) |
| { |
| uno::Sequence< sal_Int8 > buffer; |
| int len=xInputStream->readSomeBytes(buffer,maxlen); |
| if (len>0) |
| { |
| sal_Int8 *_buffer=buffer.getArray(); |
| memcpy(buf, _buffer, len); |
| bytesRead+=len; |
| if (xStatusIndicator.is()) |
| { |
| if (xSeekable.is()) |
| { |
| xStatusIndicator->setValue((int)(bytesRead*100/bytesTotal)); |
| } |
| else |
| { |
| char buf1[100]; |
| sprintf(buf1, "Converted %" SAL_PRIdINT64 " KB", bytesRead/1024); |
| xStatusIndicator->start(::rtl::OUString::createFromAscii(buf1), 0); |
| } |
| } |
| return len; |
| } |
| else |
| { |
| if (xStatusIndicator.is()) |
| { |
| xStatusIndicator->end(); |
| } |
| return 0; |
| } |
| } |
| }; |
| |
| ScannerTestService::ScannerTestService(const uno::Reference< uno::XComponentContext > &xContext_) : |
| xContext( xContext_ ) |
| { |
| } |
| |
| sal_Int32 SAL_CALL ScannerTestService::run( const uno::Sequence< rtl::OUString >& aArguments ) throw (uno::RuntimeException) |
| { |
| |
| printf("TEST\n"); |
| |
| uno::Sequence<uno::Any> aUcbInitSequence(2); |
| aUcbInitSequence[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local")); |
| aUcbInitSequence[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office")); |
| uno::Reference<lang::XMultiServiceFactory> xServiceFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW); |
| printf("A\n"); |
| uno::Reference<lang::XMultiComponentFactory> xFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW ); |
| printf("B\n"); |
| if (::ucbhelper::ContentBroker::initialize(xServiceFactory, aUcbInitSequence)) |
| { |
| printf("C\n"); |
| rtl::OUString arg=aArguments[0]; |
| |
| uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess( |
| xFactory->createInstanceWithContext( |
| ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")), |
| xContext), uno::UNO_QUERY_THROW ); |
| |
| rtl_uString *dir=NULL; |
| osl_getProcessWorkingDir(&dir); |
| rtl::OUString absFileUrl; |
| osl_getAbsoluteFileURL(dir, arg.pData, &absFileUrl.pData); |
| rtl_uString_release(dir); |
| |
| uno::Reference <lang::XSingleServiceFactory> xStorageFactory( |
| xServiceFactory->createInstance (rtl::OUString::createFromAscii("com.sun.star.embed.StorageFactory")), uno::UNO_QUERY_THROW); |
| |
| rtl::OUString outFileUrl; |
| { |
| rtl_uString *dir1=NULL; |
| osl_getProcessWorkingDir(&dir1); |
| osl_getAbsoluteFileURL(dir1, aArguments[1].pData, &outFileUrl.pData); |
| rtl_uString_release(dir1); |
| } |
| |
| uno::Sequence< uno::Any > aArgs2( 2 ); |
| aArgs2[0] <<= outFileUrl; |
| aArgs2[1] <<= embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE; |
| uno::Reference<embed::XStorage> xStorage(xStorageFactory->createInstanceWithArguments(aArgs2), uno::UNO_QUERY_THROW); |
| uno::Reference<beans::XPropertySet> xPropSet(xStorage, uno::UNO_QUERY_THROW); |
| xPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.oasis.opendocument.text"))); |
| uno::Reference<io::XInputStream> xInputStream = xFileAccess->openFileRead(absFileUrl); |
| uno::Reference< task::XStatusIndicator > xStatusIndicator; |
| |
| TimeValue t1; osl_getSystemTime(&t1); |
| |
| RtfInputSourceImpl rtfInputSource(xInputStream, xStatusIndicator); |
| MyRtfScannerHandler eventHandler(xServiceFactory, xFileAccess, xStorage); |
| writerfilter::rtftok::RTFScanner *rtfScanner=writerfilter::rtftok::RTFScanner::createRTFScanner(rtfInputSource, eventHandler); |
| |
| rtfScanner->yylex(); |
| delete rtfScanner; |
| |
| TimeValue t2; osl_getSystemTime(&t2); |
| printf("time=%" SAL_PRIuUINT32 "s\n", t2.Seconds-t1.Seconds); |
| |
| // eventHandler.dump(); |
| uno::Reference<embed::XTransactedObject> xTransact(xStorage, uno::UNO_QUERY); |
| xTransact->commit(); |
| |
| |
| ::ucbhelper::ContentBroker::deinitialize(); |
| } |
| else |
| { |
| fprintf(stderr, "can't initialize UCB"); |
| } |
| return 0; |
| } |
| |
| ::rtl::OUString ScannerTestService_getImplementationName () |
| { |
| return rtl::OUString::createFromAscii ( ScannerTestService::IMPLEMENTATION_NAME ); |
| } |
| |
| sal_Bool SAL_CALL ScannerTestService_supportsService( const ::rtl::OUString& ServiceName ) |
| { |
| return ServiceName.equals( rtl::OUString::createFromAscii( ScannerTestService::SERVICE_NAME ) ); |
| } |
| uno::Sequence< rtl::OUString > SAL_CALL ScannerTestService_getSupportedServiceNames( ) throw (uno::RuntimeException) |
| { |
| uno::Sequence < rtl::OUString > aRet(1); |
| rtl::OUString* pArray = aRet.getArray(); |
| pArray[0] = rtl::OUString::createFromAscii ( ScannerTestService::SERVICE_NAME ); |
| return aRet; |
| } |
| |
| uno::Reference< uno::XInterface > SAL_CALL ScannerTestService_createInstance( const uno::Reference< uno::XComponentContext > & xContext) throw( uno::Exception ) |
| { |
| return (cppu::OWeakObject*) new ScannerTestService( xContext ); |
| } |
| |
| } } /* end namespace writerfilter::rtftok */ |