1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_i18npool.hxx" 30 31 #include <stdio.h> 32 #include <string.h> 33 #include <stack> 34 35 #include "sal/main.h" 36 37 #include <com/sun/star/lang/XComponent.hpp> 38 39 #include <com/sun/star/xml/sax/SAXParseException.hpp> 40 #include <com/sun/star/xml/sax/XParser.hpp> 41 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> 42 43 #include <com/sun/star/io/XOutputStream.hpp> 44 #include <com/sun/star/io/XActiveDataSource.hpp> 45 46 #include <cppuhelper/servicefactory.hxx> 47 #include <cppuhelper/implbase1.hxx> 48 #include <cppuhelper/implbase3.hxx> 49 50 #include <vos/diagnose.hxx> 51 52 #include "LocaleNode.hxx" 53 54 using namespace ::rtl; 55 using namespace ::std; 56 using namespace ::cppu; 57 using namespace ::com::sun::star::uno; 58 using namespace ::com::sun::star::lang; 59 using namespace ::com::sun::star::registry; 60 using namespace ::com::sun::star::xml::sax; 61 using namespace ::com::sun::star::io; 62 63 64 65 66 67 68 /************ 69 * Sequence of bytes -> InputStream 70 ************/ 71 class OInputStream : public WeakImplHelper1 < XInputStream > 72 { 73 public: 74 OInputStream( const Sequence< sal_Int8 >&seq ) : 75 nPos( 0 ), 76 m_seq( seq ) 77 {} 78 79 public: 80 virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) 81 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 82 { 83 nBytesToRead = (nBytesToRead > m_seq.getLength() - nPos ) ? 84 m_seq.getLength() - nPos : 85 nBytesToRead; 86 aData = Sequence< sal_Int8 > ( &(m_seq.getConstArray()[nPos]) , nBytesToRead ); 87 nPos += nBytesToRead; 88 return nBytesToRead; 89 } 90 virtual sal_Int32 SAL_CALL readSomeBytes( 91 ::com::sun::star::uno::Sequence< sal_Int8 >& aData, 92 sal_Int32 nMaxBytesToRead ) 93 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 94 { 95 return readBytes( aData, nMaxBytesToRead ); 96 } 97 virtual void SAL_CALL skipBytes( sal_Int32 /*nBytesToSkip*/ ) 98 throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) 99 { 100 // not implemented 101 } 102 virtual sal_Int32 SAL_CALL available( ) 103 throw(NotConnectedException, IOException, RuntimeException) 104 { 105 return m_seq.getLength() - nPos; 106 } 107 virtual void SAL_CALL closeInput( ) 108 throw(NotConnectedException, IOException, RuntimeException) 109 { 110 // not needed 111 } 112 sal_Int32 nPos; 113 Sequence< sal_Int8> m_seq; 114 }; 115 116 //------------------------------- 117 // Helper : create an input stream from a file 118 //------------------------------ 119 Reference< XInputStream > createStreamFromFile( 120 const char *pcFile ) 121 { 122 FILE *f = fopen( pcFile , "rb" ); 123 Reference< XInputStream > r; 124 125 if( f ) { 126 fseek( f , 0 , SEEK_END ); 127 size_t nLength = ftell( f ); 128 fseek( f , 0 , SEEK_SET ); 129 130 Sequence<sal_Int8> seqIn(nLength); 131 if (fread( seqIn.getArray() , nLength , 1 , f ) == 1) 132 r = Reference< XInputStream > ( new OInputStream( seqIn ) ); 133 else 134 fprintf(stderr, "failure reading %s\n", pcFile); 135 fclose( f ); 136 } 137 return r; 138 } 139 140 141 class TestDocumentHandler : 142 public WeakImplHelper3< XExtendedDocumentHandler , XEntityResolver , XErrorHandler > 143 { 144 public: 145 TestDocumentHandler(const char* locale, const char* outFile ) : 146 rootNode(0), nError(0), nbOfCurrencies(0), nbOfCalendars(0), nbOfFormatElements(0), 147 nbOfTransliterations(0), nbOfCollations(0), nbOfDays(50), nbOfMonths(50), nbOfEras(10), 148 flag(-1), of(outFile, locale), isStartDayOfWeek(false), foundDefaultName(false), 149 foundVariant(false), openElement(false) 150 { 151 strncpy( theLocale, locale, sizeof(theLocale) ); 152 theLocale[sizeof(theLocale)-1] = 0; 153 } 154 155 ~TestDocumentHandler( ) 156 { 157 of.closeOutput(); 158 } 159 160 161 public: // Error handler 162 virtual void SAL_CALL error(const Any& aSAXParseException) throw (SAXException, RuntimeException) 163 { 164 ++nError; 165 printf( "Error !\n" ); 166 throw SAXException( 167 OUString( RTL_CONSTASCII_USTRINGPARAM("error from error handler")) , 168 Reference < XInterface >() , 169 aSAXParseException ); 170 } 171 virtual void SAL_CALL fatalError(const Any& /*aSAXParseException*/) throw (SAXException, RuntimeException) 172 { 173 ++nError; 174 printf( "Fatal Error !\n" ); 175 } 176 virtual void SAL_CALL warning(const Any& /*aSAXParseException*/) throw (SAXException, RuntimeException) 177 { 178 printf( "Warning !\n" ); 179 } 180 181 182 public: // ExtendedDocumentHandler 183 184 185 186 stack<LocaleNode *> currentNode ; 187 sal_Bool fElement ; 188 LocaleNode * rootNode; 189 190 virtual void SAL_CALL startDocument(void) throw (SAXException, RuntimeException) 191 { 192 printf( "parsing document %s started\n", theLocale); 193 of.writeAsciiString("#include <sal/types.h>\n\n\n"); 194 of.writeAsciiString("#include <stdio.h> // debug printfs\n\n"); 195 of.writeAsciiString("extern \"C\" {\n\n"); 196 } 197 198 virtual void SAL_CALL endDocument(void) throw (SAXException, RuntimeException) 199 { 200 if (rootNode) 201 { 202 rootNode->generateCode(of); 203 int err = rootNode->getError(); 204 if (err) 205 { 206 printf( "Error: in data for %s: %d\n", theLocale, err); 207 nError += err; 208 } 209 } 210 else 211 { 212 ++nError; 213 printf( "Error: no data for %s\n", theLocale); 214 } 215 printf( "parsing document %s finished\n", theLocale); 216 217 of.writeAsciiString("} // extern \"C\"\n\n"); 218 of.closeOutput(); 219 } 220 221 virtual void SAL_CALL startElement(const OUString& aName, 222 const Reference< XAttributeList > & xAttribs) 223 throw (SAXException,RuntimeException) 224 { 225 226 LocaleNode * l = LocaleNode::createNode (aName, xAttribs); 227 if (!currentNode.empty() ) { 228 LocaleNode * ln = (LocaleNode *) currentNode . top(); 229 ln->addChild(l); 230 } else { 231 rootNode = l; 232 } 233 currentNode . push (l); 234 } 235 236 237 virtual void SAL_CALL endElement(const OUString& /*aName*/) throw (SAXException,RuntimeException) 238 { 239 currentNode . pop(); 240 } 241 242 virtual void SAL_CALL characters(const OUString& aChars) throw (SAXException,RuntimeException) 243 { 244 245 LocaleNode * l = currentNode . top(); 246 l->setValue (aChars); 247 ::rtl::OUString str(aChars); 248 sal_Unicode nonBreakSPace[2]= {0xa, 0x0}; 249 if(!openElement || str.equals(nonBreakSPace)) 250 return; 251 } 252 253 virtual void SAL_CALL ignorableWhitespace(const OUString& /*aWhitespaces*/) throw (SAXException,RuntimeException) 254 { 255 } 256 257 virtual void SAL_CALL processingInstruction(const OUString& /*aTarget*/, const OUString& /*aData*/) throw (SAXException,RuntimeException) 258 { 259 // ignored 260 } 261 262 virtual void SAL_CALL setDocumentLocator(const Reference< XLocator> & /*xLocator*/) 263 throw (SAXException,RuntimeException) 264 { 265 // ignored 266 } 267 268 virtual InputSource SAL_CALL resolveEntity( 269 const OUString& sPublicId, 270 const OUString& sSystemId) 271 throw (RuntimeException) 272 { 273 InputSource source; 274 source.sSystemId = sSystemId; 275 source.sPublicId = sPublicId; 276 277 source.aInputStream = createStreamFromFile( 278 OUStringToOString( sSystemId , RTL_TEXTENCODING_ASCII_US) ); 279 280 return source; 281 } 282 283 virtual void SAL_CALL startCDATA(void) throw (SAXException,RuntimeException) 284 { 285 } 286 virtual void SAL_CALL endCDATA(void) throw (RuntimeException) 287 { 288 } 289 virtual void SAL_CALL comment(const OUString& /*sComment*/) throw (SAXException,RuntimeException) 290 { 291 } 292 virtual void SAL_CALL unknown(const OUString& /*sString*/) throw (SAXException,RuntimeException) 293 { 294 } 295 296 virtual void SAL_CALL allowLineBreak( void) throw (SAXException, RuntimeException ) 297 { 298 299 } 300 301 public: 302 int nError; 303 ::rtl::OUString currentElement; 304 sal_Int16 nbOfCurrencies; 305 sal_Int16 nbOfCalendars; 306 sal_Int16 nbOfFormatElements; 307 sal_Int16 nbOfTransliterations; 308 sal_Int16 nbOfCollations; 309 Sequence<sal_Int16> nbOfDays; 310 Sequence<sal_Int16> nbOfMonths; 311 Sequence<sal_Int16> nbOfEras; 312 sal_Char *elementTag; 313 sal_Char theLocale[50]; 314 sal_Int16 flag; 315 OFileWriter of; 316 sal_Bool isStartDayOfWeek; 317 sal_Bool foundDefaultName; 318 sal_Bool foundVariant; 319 sal_Bool openElement; 320 }; 321 322 323 324 325 326 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) 327 { 328 329 330 if( argc < 6) { 331 printf( "usage : %s <locaLe> <XML inputfile> <destination file> <services.rdb location> <types.rdb location>\n", argv[0] ); 332 exit( 1 ); 333 } 334 335 // create service manager 336 Reference< XMultiServiceFactory > xSMgr; 337 try 338 { 339 xSMgr = createRegistryServiceFactory( 340 ::rtl::OUString::createFromAscii(argv[4]), 341 ::rtl::OUString::createFromAscii(argv[5]), true ); 342 } 343 catch ( Exception& ) 344 { 345 printf( "Exception on createRegistryServiceFactory\n" ); 346 exit(1); 347 } 348 349 //-------------------------------- 350 // parser demo 351 // read xml from a file and count elements 352 //-------------------------------- 353 Reference< XInterface > x = xSMgr->createInstance( 354 OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) ); 355 int nError = 0; 356 if( x.is() ) 357 { 358 Reference< XParser > rParser( x , UNO_QUERY ); 359 360 // create and connect the document handler to the parser 361 TestDocumentHandler *pDocHandler = new TestDocumentHandler( argv[1], argv[3]); 362 363 Reference < XDocumentHandler > rDocHandler( (XDocumentHandler *) pDocHandler ); 364 Reference< XEntityResolver > rEntityResolver( (XEntityResolver *) pDocHandler ); 365 366 rParser->setDocumentHandler( rDocHandler ); 367 rParser->setEntityResolver( rEntityResolver ); 368 369 // create the input stream 370 InputSource source; 371 source.aInputStream = createStreamFromFile( argv[2] ); 372 source.sSystemId = OUString::createFromAscii( argv[2] ); 373 374 try 375 { 376 // start parsing 377 rParser->parseStream( source ); 378 } 379 380 catch( Exception & e ) 381 { 382 OString o1 = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8 ); 383 printf( "Exception during parsing : %s\n" , o1.getStr() ); 384 exit(1); 385 } 386 nError = pDocHandler->nError; 387 } 388 else 389 { 390 printf( "couln't create sax-parser component\n" ); 391 exit(1); 392 } 393 394 return nError; 395 } 396