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