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 << "<"; break;
86 case '>': cout << ">"; break;
87 case '&': cout << "&"; 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