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 "XMLScanner.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 <string>
43 #include <cppuhelper/implbase2.hxx>
44 #include <com/sun/star/embed/XTransactedObject.hpp>
45 #include <com/sun/star/embed/XStorage.hpp>
46 #include <com/sun/star/util/XCloseable.hpp>
47 #include <comphelper/storagehelper.hxx>
48 #include <com/sun/star/embed/XTransactedObject.hpp>
49 #include <com/sun/star/beans/PropertyValue.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <comphelper/seqstream.hxx>
52 
53 #include <ctype.h>
54 #include <iostream>
55 
56 using namespace ::com::sun::star;
57 using namespace ::std;
58 
59 namespace writerfilter { namespace rtftok {
60 
61 const sal_Char XMLScanner::SERVICE_NAME[40] = "debugservices.rtftok.XMLScanner";
62 const sal_Char XMLScanner::IMPLEMENTATION_NAME[40] = "debugservices.rtftok.XMLScanner";
63 
64 class XmlRtfScannerHandler : public writerfilter::rtftok::RTFScannerHandler
65 {
66 	std::vector<unsigned char> binBuffer;
67 	int objDataLevel;
68 	int numOfOLEs;
69 	unsigned char hb;
70 	int numOfOLEChars;
71 	uno::Reference<lang::XMultiServiceFactory> xServiceFactory;
72 	uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess;
73     string charBuffer;
74     string ucharBuffer;
75     vector<string> vCloseTags;
76 
xmlout(const string & str)77     void xmlout(const string & str)
78     {
79         for (size_t n = 0; n < str.length(); ++n)
80         {
81             char c = str[n];
82 
83             switch (c)
84             {
85             case '<': cout << "&lt;"; break;
86             case '>': cout << "&gt;"; break;
87             case '&': cout << "&amp;"; break;
88             default:
89                 cout << c;
90 
91                 break;
92             }
93         }
94     }
95 
clearBuffers()96     void clearBuffers()
97     {
98         if (charBuffer.length() > 0)
99         {
100             cout << "<text>";
101             xmlout(charBuffer);
102             cout << "</text>" << endl;
103         }
104 
105         charBuffer = "";
106 
107         if (ucharBuffer.length() > 0)
108         {
109             cout << "<utext>";
110             xmlout(ucharBuffer);
111             cout << ucharBuffer << "</utext>" << endl;
112         }
113 
114         ucharBuffer = "";
115     }
116 
dest(char * token,char * value)117 	void dest(char* token, char* value)
118 	{
119         clearBuffers();
120         cout << "<dest name=\"" << token << "\" value=\""<< value << "\">" << endl;
121         vCloseTags.push_back("</dest>");
122 	}
ctrl(char * token,char * value)123 	void ctrl(char*token, char* value)
124 	{
125         clearBuffers();
126         cout << "<" << token << ">" << value << "</" << token << ">"
127              << endl;
128 	}
lbrace(void)129 	void lbrace(void)
130 	{
131         clearBuffers();
132         cout << "<brace>" << endl;
133         vCloseTags.push_back("</brace>");
134 	}
rbrace(void)135 	void rbrace(void)
136 	{
137         clearBuffers();
138         cout << vCloseTags.back() << endl;
139         vCloseTags.pop_back();
140 	}
addSpaces(int count)141 	void addSpaces(int count)
142 	{
143         clearBuffers();
144         cout << "<spaces count=\"" << count << "\"/>" << endl;
145 	}
addBinData(unsigned char)146 	void addBinData(unsigned char /*data*/)
147 	{
148         clearBuffers();
149         cout << "<bindata/>" << endl;
150 	}
addChar(char ch)151 	void addChar(char ch)
152 	{
153         charBuffer += ch;
154 	}
addCharU(sal_Unicode ch)155 	void addCharU(sal_Unicode ch)
156 	{
157         ucharBuffer += sal_Char(ch < 128 ? ch : '.');
158 	}
addHexChar(char * hexch)159 	void addHexChar(char* hexch)
160 	{
161         clearBuffers();
162         cout << "<hexchar value=\"" << hexch << "\"/>" << endl;
163 	}
164 
165 public:
XmlRtfScannerHandler(uno::Reference<lang::XMultiServiceFactory> & xServiceFactory_,uno::Reference<com::sun::star::ucb::XSimpleFileAccess> & xFileAccess_)166 	XmlRtfScannerHandler(uno::Reference<lang::XMultiServiceFactory> &xServiceFactory_, uno::Reference<com::sun::star::ucb::XSimpleFileAccess> &xFileAccess_) :
167             objDataLevel(0), numOfOLEs(0), hb(' '), numOfOLEChars(0),
168     xServiceFactory(xServiceFactory_),
169     xFileAccess(xFileAccess_)
170 	{
171 	}
172 
~XmlRtfScannerHandler()173     virtual ~XmlRtfScannerHandler() {}
174 
dump()175 	void dump()
176 	{
177 	}
178 };
179 
180 class RtfInputSourceImpl : public rtftok::RTFInputSource
181 {
182 private:
183 	uno::Reference< io::XInputStream > xInputStream;
184 	uno::Reference< io::XSeekable > xSeekable;
185 	uno::Reference< task::XStatusIndicator > xStatusIndicator;
186 	sal_Int64 bytesTotal;
187 	sal_Int64 bytesRead;
188 public:
RtfInputSourceImpl(uno::Reference<io::XInputStream> & xInputStream_,uno::Reference<task::XStatusIndicator> & xStatusIndicator_)189 	RtfInputSourceImpl(uno::Reference< io::XInputStream > &xInputStream_, uno::Reference< task::XStatusIndicator > &xStatusIndicator_) :
190 	  xInputStream(xInputStream_),
191 	  xStatusIndicator(xStatusIndicator_),
192 	  bytesRead(0)
193 	{
194 		xSeekable=uno::Reference< io::XSeekable >(xInputStream, uno::UNO_QUERY);
195 		if (xSeekable.is())
196 			bytesTotal=xSeekable->getLength();
197 		if (xStatusIndicator.is() && xSeekable.is())
198 		{
199 			xStatusIndicator->start(::rtl::OUString::createFromAscii("Converting"), 100);
200 		}
201 	}
202 
~RtfInputSourceImpl()203     virtual ~RtfInputSourceImpl() {}
204 
read(void * buf,int maxlen)205 	int read(void *buf, int maxlen)
206 	{
207 		uno::Sequence< sal_Int8 > buffer;
208 		int len=xInputStream->readSomeBytes(buffer,maxlen);
209 		if (len>0)
210 		{
211 			sal_Int8 *_buffer=buffer.getArray();
212 			memcpy(buf, _buffer, len);
213 			bytesRead+=len;
214 			if (xStatusIndicator.is())
215 			{
216 				if (xSeekable.is())
217 				{
218 					xStatusIndicator->setValue((int)(bytesRead*100/bytesTotal));
219 				}
220 				else
221 				{
222 					char buf1[100];
223 					sprintf(buf1, "Converted %" SAL_PRIdINT64 " KB", bytesRead/1024);
224 					xStatusIndicator->start(::rtl::OUString::createFromAscii(buf1), 0);
225 				}
226 			}
227 			return len;
228 		}
229 		else
230 		{
231 			if (xStatusIndicator.is())
232 			{
233 				xStatusIndicator->end();
234 			}
235 			return 0;
236 		}
237 	}
238 };
239 
XMLScanner(const uno::Reference<uno::XComponentContext> & xContext_)240 XMLScanner::XMLScanner(const uno::Reference< uno::XComponentContext > &xContext_) :
241 xContext( xContext_ )
242 {
243 }
244 
run(const uno::Sequence<rtl::OUString> & aArguments)245 sal_Int32 SAL_CALL XMLScanner::run( const uno::Sequence< rtl::OUString >& aArguments ) throw (uno::RuntimeException)
246 {
247   	uno::Sequence<uno::Any> aUcbInitSequence(2);
248 	aUcbInitSequence[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
249 	aUcbInitSequence[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
250 	uno::Reference<lang::XMultiServiceFactory> xServiceFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW);
251 	uno::Reference<lang::XMultiComponentFactory> xFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW );
252     if (::ucbhelper::ContentBroker::initialize(xServiceFactory, aUcbInitSequence))
253 	{
254 			rtl::OUString arg=aArguments[0];
255 
256 			uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess(
257 			xFactory->createInstanceWithContext(
258 				::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")),
259 				xContext), uno::UNO_QUERY_THROW );
260 
261 			rtl_uString *dir=NULL;
262 			osl_getProcessWorkingDir(&dir);
263 			rtl::OUString absFileUrl;
264 			osl_getAbsoluteFileURL(dir, arg.pData, &absFileUrl.pData);
265 			rtl_uString_release(dir);
266 
267 			uno::Reference <lang::XSingleServiceFactory> xStorageFactory(
268 				xServiceFactory->createInstance (rtl::OUString::createFromAscii("com.sun.star.embed.StorageFactory")), uno::UNO_QUERY_THROW);
269 
270 #if 0
271 			rtl::OUString outFileUrl;
272 			{
273 			rtl_uString *dir1=NULL;
274 			osl_getProcessWorkingDir(&dir1);
275 			osl_getAbsoluteFileURL(dir1, aArguments[1].pData, &outFileUrl.pData);
276 			rtl_uString_release(dir1);
277 			}
278 
279 			uno::Sequence< uno::Any > aArgs( 2 );
280 			aArgs[0] <<= outFileUrl;
281 			aArgs[1] <<= embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE;
282 			uno::Reference<embed::XStorage> xStorage(xStorageFactory->createInstanceWithArguments(aArgs), uno::UNO_QUERY_THROW);
283 			uno::Reference<beans::XPropertySet> xPropSet(xStorage, uno::UNO_QUERY_THROW);
284 			xPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.oasis.opendocument.text")));
285 #endif
286 			uno::Reference<io::XInputStream> xInputStream = xFileAccess->openFileRead(absFileUrl);
287 			uno::Reference< task::XStatusIndicator > xStatusIndicator;
288 
289 			RtfInputSourceImpl rtfInputSource(xInputStream, xStatusIndicator);
290 			XmlRtfScannerHandler eventHandler(xServiceFactory, xFileAccess);
291 			writerfilter::rtftok::RTFScanner *rtfScanner=writerfilter::rtftok::RTFScanner::createRTFScanner(rtfInputSource, eventHandler);
292 
293             cout << "<out>" << endl;
294 			rtfScanner->yylex();
295             cout << "</out>" << endl;
296 			delete rtfScanner;
297 
298         ::ucbhelper::ContentBroker::deinitialize();
299 	}
300 	else
301 	{
302 		fprintf(stderr, "can't initialize UCB");
303 	}
304 	return 0;
305 }
306 
XMLScanner_getImplementationName()307 ::rtl::OUString XMLScanner_getImplementationName ()
308 {
309 	return rtl::OUString::createFromAscii ( XMLScanner::IMPLEMENTATION_NAME );
310 }
311 
XMLScanner_supportsService(const::rtl::OUString & ServiceName)312 sal_Bool SAL_CALL XMLScanner_supportsService( const ::rtl::OUString& ServiceName )
313 {
314 	return ServiceName.equals( rtl::OUString::createFromAscii( XMLScanner::SERVICE_NAME ) );
315 }
XMLScanner_getSupportedServiceNames()316 uno::Sequence< rtl::OUString > SAL_CALL XMLScanner_getSupportedServiceNames(  ) throw (uno::RuntimeException)
317 {
318 	uno::Sequence < rtl::OUString > aRet(1);
319 	rtl::OUString* pArray = aRet.getArray();
320 	pArray[0] =  rtl::OUString::createFromAscii ( XMLScanner::SERVICE_NAME );
321 	return aRet;
322 }
323 
XMLScanner_createInstance(const uno::Reference<uno::XComponentContext> & xContext)324 uno::Reference< uno::XInterface > SAL_CALL XMLScanner_createInstance( const uno::Reference< uno::XComponentContext > & xContext) throw( uno::Exception )
325 {
326 	return (cppu::OWeakObject*) new XMLScanner( xContext );
327 }
328 
329 } } /* end namespace writerfilter::rtftok */
330