1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: export2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_transex3.hxx"
34 #include "utf8conv.hxx"
35 #include <tools/datetime.hxx>
36 #include <tools/isofallback.hxx>
39 #include <osl/process.h>
40 #include <rtl/ustring.hxx>
43 #include <tools/urlobj.hxx>
51 /*****************************************************************************/
53 /*****************************************************************************/
56 // delete existing res. of type StringList
57 for ( ULONG i
= 0; i
< pStringList
->Count(); i
++ ) {
58 ExportListEntry
* test
= pStringList
->GetObject( i
);
59 if( test
!= NULL
) delete test
;
64 // delete existing res. of type FilterList
65 for ( ULONG i
= 0; i
< pFilterList
->Count(); i
++ ) {
66 ExportListEntry
* test
= pFilterList
->GetObject( i
);
72 // delete existing res. of type ItemList
73 for ( ULONG i
= 0; i
< pItemList
->Count(); i
++ ) {
74 ExportListEntry
* test
= pItemList
->GetObject( i
);
80 // delete existing res. of type UIEntries
81 for ( ULONG i
= 0; i
< pUIEntries
->Count(); i
++ ) {
82 ExportListEntry
* test
= pUIEntries
->GetObject( i
);
93 /*****************************************************************************/
94 ByteString
Export::sLanguages
;
95 ByteString
Export::sForcedLanguages
;
96 ByteString
Export::sIsoCode99
;
97 /*****************************************************************************/
99 void Export::DumpExportList( ByteString
& sListName
, ExportList
& aList
){
100 printf( "%s\n", sListName
.GetBuffer() );
102 ExportListEntry
* aEntry
;
103 for( unsigned int x
= 0; x
< aList
.Count() ; x
++ ){
104 aEntry
= (ExportListEntry
*) aList
.GetObject( x
);
105 Export::DumpMap( l
, *aEntry
);
109 ByteString
Export::DumpMap( ByteString
& sMapName
, ByteStringHashMap
& aMap
){
110 ByteStringHashMap::const_iterator idbg
;
114 printf("MapName %s\n", sMapName
.GetBuffer());
115 if( aMap
.size() < 1 ) return ByteString();
116 for( idbg
= aMap
.begin() ; idbg
!= aMap
.end(); ++idbg
){
117 ByteString
a( idbg
->first
);
118 ByteString
b( idbg
->second
);
119 printf("[%s]= %s",a
.GetBuffer(),b
.GetBuffer());
125 /*****************************************************************************/
126 void Export::SetLanguages( std::vector
<ByteString
> val
){
127 /*****************************************************************************/
129 isInitialized
= true;
131 /*****************************************************************************/
132 std::vector
<ByteString
> Export::GetLanguages(){
133 /*****************************************************************************/
136 /*****************************************************************************/
137 std::vector
<ByteString
> Export::GetForcedLanguages(){
138 /*****************************************************************************/
139 return aForcedLanguages
;
141 std::vector
<ByteString
> Export::aLanguages
= std::vector
<ByteString
>();
142 std::vector
<ByteString
> Export::aForcedLanguages
= std::vector
<ByteString
>();
145 /*****************************************************************************/
146 void Export::QuotHTMLXRM( ByteString
&rString
)
147 /*****************************************************************************/
150 //BOOL bBreak = FALSE;
151 for ( USHORT i
= 0; i
< rString
.Len(); i
++ ) {
152 ByteString sTemp
= rString
.Copy( i
);
153 if ( sTemp
.Search( "<Arg n=" ) == 0 ) {
154 while ( i
< rString
.Len() && rString
.GetChar( i
) != '>' ) {
155 sReturn
+= rString
.GetChar( i
);
158 if ( rString
.GetChar( i
) == '>' ) {
164 if ( i
< rString
.Len()) {
165 switch ( rString
.GetChar( i
)) {
167 if( i
+2 < rString
.Len() &&
168 (rString
.GetChar( i
+1 ) == 'b' || rString
.GetChar( i
+1 ) == 'B') &&
169 rString
.GetChar( i
+2 ) == '>' )
174 else if( i
+3 < rString
.Len() &&
175 rString
.GetChar( i
+1 ) == '/' &&
176 (rString
.GetChar( i
+2 ) == 'b' || rString
.GetChar( i
+2 ) == 'B') &&
177 rString
.GetChar( i
+3 ) == '>' )
199 if ((( i
+ 4 ) < rString
.Len()) &&
200 ( rString
.Copy( i
, 5 ) == "&" ))
201 sReturn
+= rString
.GetChar( i
);
207 sReturn
+= rString
.GetChar( i
);
214 /*****************************************************************************/
215 void Export::QuotHTML( ByteString
&rString
)
216 /*****************************************************************************/
219 for ( USHORT i
= 0; i
< rString
.Len(); i
++ ) {
220 ByteString sTemp
= rString
.Copy( i
);
221 if ( sTemp
.Search( "<Arg n=" ) == 0 ) {
222 while ( i
< rString
.Len() && rString
.GetChar( i
) != '>' ) {
223 sReturn
+= rString
.GetChar( i
);
226 if ( rString
.GetChar( i
) == '>' ) {
231 if ( i
< rString
.Len()) {
232 switch ( rString
.GetChar( i
)) {
250 if ((( i
+ 4 ) < rString
.Len()) &&
251 ( rString
.Copy( i
, 5 ) == "&" ))
252 sReturn
+= rString
.GetChar( i
);
258 sReturn
+= rString
.GetChar( i
);
266 void Export::RemoveUTF8ByteOrderMarker( ByteString
&rString
){
267 if( hasUTF8ByteOrderMarker( rString
) )
268 rString
.Erase( 0 , 3 );
271 bool Export::hasUTF8ByteOrderMarker( const ByteString
&rString
){
272 // Byte order marker signature
274 const unsigned char c1
= 0xEF;
275 const unsigned char c2
= 0xBB;
276 const unsigned char c3
= 0xBF;
278 const char bom
[ 3 ] = { c1
, c2
, c3
};
280 return rString
.Len() >= 3 &&
281 rString
.GetChar( 0 ) == bom
[ 0 ] &&
282 rString
.GetChar( 1 ) == bom
[ 1 ] &&
283 rString
.GetChar( 2 ) == bom
[ 2 ] ;
285 bool Export::fileHasUTF8ByteOrderMarker( const ByteString
&rString
){
286 SvFileStream
aFileIn( String( rString
, RTL_TEXTENCODING_ASCII_US
) , STREAM_READ
);
288 if( !aFileIn
.IsEof() ) {
289 aFileIn
.ReadLine( sLine
);
290 if( aFileIn
.IsOpen() ) aFileIn
.Close();
291 return hasUTF8ByteOrderMarker( sLine
);
293 if( aFileIn
.IsOpen() ) aFileIn
.Close();
296 void Export::RemoveUTF8ByteOrderMarkerFromFile( const ByteString
&rFilename
){
297 SvFileStream
aFileIn( String( rFilename
, RTL_TEXTENCODING_ASCII_US
) , STREAM_READ
);
299 if( !aFileIn
.IsEof() ) {
300 aFileIn
.ReadLine( sLine
);
302 if( hasUTF8ByteOrderMarker( sLine
) ){
303 //cout << "UTF8 Header found!\n";
304 DirEntry aTempFile
= Export::GetTempFile();
305 ByteString sTempFile
= ByteString( aTempFile
.GetFull() , RTL_TEXTENCODING_ASCII_US
);
306 SvFileStream
aNewFile( String( sTempFile
, RTL_TEXTENCODING_ASCII_US
) , STREAM_WRITE
);
308 RemoveUTF8ByteOrderMarker( sLine
);
309 //cout << "Copy stripped stuff to " << sTempFile.GetBuffer() << endl;
310 aNewFile
.WriteLine( sLine
);
312 while( !aFileIn
.IsEof() ){
313 aFileIn
.ReadLine( sLine
);
314 aNewFile
.WriteLine( sLine
);
316 if( aFileIn
.IsOpen() ) aFileIn
.Close();
317 if( aNewFile
.IsOpen() ) aNewFile
.Close();
318 DirEntry
aEntry( rFilename
.GetBuffer() );
319 //cout << "Removing file " << rFilename.GetBuffer() << "\n";
321 //cout << "Renaming file " << sTempFile.GetBuffer() << " to " << rFilename.GetBuffer() << "\n";
322 DirEntry( sTempFile
).MoveTo( DirEntry( rFilename
.GetBuffer() ) );
325 if( aFileIn
.IsOpen() ) aFileIn
.Close();
328 // Merge it into source code!
329 //bool Export::isMergingGermanAllowed( const ByteString& rPrj ){
332 /* static ByteStringBoolHashMap aHash;
334 if( aHash.find( rPrj ) != aHash.end() ){
335 return aHash[ rPrj ];
338 ByteString sFile = Export::GetEnv( "SRC_ROOT" ) ;
340 sFile.Append( rPrj );
341 sFile.Append("/prj/l10n");
342 #if defined(WNT) || defined(OS2)
343 sFile.SearchAndReplaceAll('/','\\');
345 DirEntry aFlagfile( sFile );
347 aHash[ rPrj ] = !aFlagfile.Exists();
348 return aHash[ rPrj ];*/
350 bool Export::CopyFile( const ByteString
& source
, const ByteString
& dest
)
352 // cout << "CopyFile( " << source.GetBuffer() << " , " << dest.GetBuffer() << " )\n";
353 const int BUFFERSIZE
= 8192;
354 char buf
[ BUFFERSIZE
];
356 FILE* IN_FILE
= fopen( source
.GetBuffer() , "r" );
357 FILE* OUT_FILE
= fopen( dest
.GetBuffer() , "w" );
359 if( IN_FILE
== NULL
)
361 cerr
<< "Export::CopyFile WARNING: Could not open " << source
.GetBuffer() << "\n";
364 if( OUT_FILE
== NULL
)
366 cerr
<< "Export::CopyFile WARNING: Could not open/create " << dest
.GetBuffer() << " for writing\n";
370 while( fgets( buf
, BUFFERSIZE
, IN_FILE
) != NULL
)
372 if( fputs( buf
, OUT_FILE
) == EOF
)
374 cerr
<< "Export::CopyFile WARNING: Write problems " << source
.GetBuffer() << "\n";
380 if( ferror( IN_FILE
) )
382 cerr
<< "Export::CopyFile WARNING: Read problems " << dest
.GetBuffer() << "\n";
393 /*****************************************************************************/
394 void Export::UnquotHTML( ByteString
&rString
)
395 /*****************************************************************************/
398 while ( rString
.Len()) {
399 if ( rString
.Copy( 0, 5 ) == "&" ) {
401 rString
.Erase( 0, 5 );
403 else if ( rString
.Copy( 0, 4 ) == "<" ) {
405 rString
.Erase( 0, 4 );
407 else if ( rString
.Copy( 0, 4 ) == ">" ) {
409 rString
.Erase( 0, 4 );
411 else if ( rString
.Copy( 0, 6 ) == """ ) {
413 rString
.Erase( 0, 6 );
415 else if ( rString
.Copy( 0, 6 ) == "'" ) {
417 rString
.Erase( 0, 6 );
420 sReturn
+= rString
.GetChar( 0 );
421 rString
.Erase( 0, 1 );
426 bool Export::isSourceLanguage( const ByteString
&sLanguage
)
428 return !isAllowed( sLanguage
);
430 bool Export::isAllowed( const ByteString
&sLanguage
){
431 return ! ( sLanguage
.EqualsIgnoreCaseAscii("en-US") );
433 /*****************************************************************************/
434 bool Export::LanguageAllowed( const ByteString
&nLanguage
)
435 /*****************************************************************************/
437 return std::find( aLanguages
.begin() , aLanguages
.end() , nLanguage
) != aLanguages
.end();
440 bool Export::isInitialized
= false;
442 /*****************************************************************************/
443 void Export::InitLanguages( bool bMergeMode
){
444 /*****************************************************************************/
445 if( !isInitialized
){
447 ByteStringBoolHashMap aEnvLangs
;
448 for ( USHORT x
= 0; x
< sLanguages
.GetTokenCount( ',' ); x
++ ){
449 sTmp
= sLanguages
.GetToken( x
, ',' ).GetToken( 0, '=' );
450 sTmp
.EraseLeadingAndTrailingChars();
451 if( bMergeMode
&& !isAllowed( sTmp
) ){}
452 else if( !( (sTmp
.GetChar(0)=='x' || sTmp
.GetChar(0)=='X') && sTmp
.GetChar(1)=='-' ) ){
453 aLanguages
.push_back( sTmp
);
456 InitForcedLanguages( bMergeMode
);
457 isInitialized
= true;
460 /*****************************************************************************/
461 void Export::InitForcedLanguages( bool bMergeMode
){
462 /*****************************************************************************/
464 ByteStringBoolHashMap aEnvLangs
;
465 for ( USHORT x
= 0; x
< sForcedLanguages
.GetTokenCount( ',' ); x
++ ){
466 sTmp
= sForcedLanguages
.GetToken( x
, ',' ).GetToken( 0, '=' );
467 sTmp
.EraseLeadingAndTrailingChars();
468 if( bMergeMode
&& isAllowed( sTmp
) ){}
469 else if( !( (sTmp
.GetChar(0)=='x' || sTmp
.GetChar(0)=='X') && sTmp
.GetChar(1)=='-' ) )
470 aForcedLanguages
.push_back( sTmp
);
474 /*****************************************************************************/
475 ByteString
Export::GetFallbackLanguage( const ByteString nLanguage
)
476 /*****************************************************************************/
478 ByteString sFallback
=nLanguage
;
479 GetIsoFallback( sFallback
);
483 void Export::replaceEncoding( ByteString
& rString
)
485 // ™ -> \u2122
487 for( xub_StrLen idx
= 0; idx
<= rString
.Len()-8 ; idx
++ )
489 if( rString
.GetChar( idx
) == '&' &&
490 rString
.GetChar( idx
+1 ) == '#' &&
491 rString
.GetChar( idx
+2 ) == 'x' &&
492 rString
.GetChar( idx
+7 ) == ';' )
494 ByteString sTmp
= rString
.Copy( 0 , idx
);
495 sTmp
.Append( "\\u" );
496 sTmp
.Append( rString
.GetChar( idx
+3 ) );
497 sTmp
.Append( rString
.GetChar( idx
+4 ) );
498 sTmp
.Append( rString
.GetChar( idx
+5 ) );
499 sTmp
.Append( rString
.GetChar( idx
+6 ) );
500 sTmp
.Append( rString
.Copy( idx
+8 , rString
.Len() ) );
506 /*****************************************************************************/
507 void Export::FillInFallbacks( ResData
*pResData
)
508 /*****************************************************************************/
511 for( unsigned int n
= 0; n
< aLanguages
.size(); n
++ ){
512 sCur
= aLanguages
[ n
];
513 if( isAllowed( sCur
) ){
514 ByteString nFallbackIndex
= GetFallbackLanguage( sCur
);
515 if( nFallbackIndex
.Len() ){
516 if ( !pResData
->sText
[ sCur
].Len())
517 pResData
->sText
[ sCur
] =
518 pResData
->sText
[ nFallbackIndex
];
520 if ( !pResData
->sHelpText
[ sCur
].Len())
521 pResData
->sHelpText
[ sCur
] =
522 pResData
->sHelpText
[ nFallbackIndex
];
524 if ( !pResData
->sQuickHelpText
[ sCur
].Len())
525 pResData
->sQuickHelpText
[ sCur
] =
526 pResData
->sQuickHelpText
[ nFallbackIndex
];
528 if ( !pResData
->sTitle
[ sCur
].Len())
529 pResData
->sTitle
[ sCur
] =
530 pResData
->sTitle
[ nFallbackIndex
];
532 if ( pResData
->pStringList
)
534 pResData
->pStringList
, sCur
, nFallbackIndex
);
536 if ( pResData
->pPairedList
)
538 pResData
->pPairedList
, sCur
, nFallbackIndex
);
540 if ( pResData
->pFilterList
)
542 pResData
->pFilterList
, sCur
, nFallbackIndex
);
544 if ( pResData
->pItemList
)
546 pResData
->pItemList
, sCur
, nFallbackIndex
);
548 if ( pResData
->pUIEntries
)
550 pResData
->pUIEntries
, sCur
, nFallbackIndex
);
556 /*****************************************************************************/
557 void Export::FillInListFallbacks(
558 ExportList
*pList
, const ByteString
&nSource
, const ByteString
&nFallback
)
559 /*****************************************************************************/
562 for ( ULONG i
= 0; i
< pList
->Count(); i
++ ) {
563 ExportListEntry
*pEntry
= pList
->GetObject( i
);
564 if ( !( *pEntry
)[ nSource
].Len()){
565 ( *pEntry
)[ nSource
] = ( *pEntry
)[ nFallback
];
566 ByteString x
= ( *pEntry
)[ nSource
];
567 ByteString y
= ( *pEntry
)[ nFallback
];
572 /*****************************************************************************/
573 ByteString
Export::GetTimeStamp()
574 /*****************************************************************************/
576 // return "xx.xx.xx";
580 snprintf(buf
, sizeof(buf
), "%8d %02d:%02d:%02d", int(Date().GetDate()),
581 int(aTime
.GetHour()), int(aTime
.GetMin()), int(aTime
.GetSec()));
582 return ByteString(buf
);
585 /*****************************************************************************/
586 BOOL
Export::ConvertLineEnds(
587 ByteString sSource
, ByteString sDestination
)
588 /*****************************************************************************/
590 String
sSourceFile( sSource
, RTL_TEXTENCODING_ASCII_US
);
591 String
sDestinationFile( sDestination
, RTL_TEXTENCODING_ASCII_US
);
593 SvFileStream
aSource( sSourceFile
, STREAM_READ
);
594 if ( !aSource
.IsOpen())
596 SvFileStream
aDestination( sDestinationFile
, STREAM_STD_WRITE
| STREAM_TRUNC
);
597 if ( !aDestination
.IsOpen()) {
604 while ( !aSource
.IsEof()) {
605 aSource
.ReadLine( sLine
);
606 if ( !aSource
.IsEof()) {
607 sLine
.EraseAllChars( '\r' );
608 aDestination
.WriteLine( sLine
);
611 aDestination
.WriteByteString( sLine
);
615 aDestination
.Close();
620 /*****************************************************************************/
621 ByteString
Export::GetNativeFile( ByteString sSource
)
622 /*****************************************************************************/
624 DirEntry
aTemp( GetTempFile());
625 ByteString
sReturn( aTemp
.GetFull(), RTL_TEXTENCODING_ASCII_US
);
627 for ( USHORT i
= 0; i
< 10; i
++ )
628 if ( ConvertLineEnds( sSource
, sReturn
))
634 const char* Export::GetEnv( const char *pVar
)
636 char *pRet
= getenv( pVar
);
643 int Export::getCurrentDirectory( rtl::OUString
& base_fqurl_out
, rtl::OUString
& base_out
)
647 base_out
= rtl::OUString( aDir
.GetFull() );
648 return osl::File::getFileURLFromSystemPath( base_out
, base_fqurl_out
);
652 // Stolen from sal/osl/unx/tempfile.c
654 #define RAND_NAME_LENGTH 6
656 void Export::getRandomName( const ByteString
& sPrefix
, ByteString
& sRandStr
, const ByteString
& sPostfix
)
658 static const char LETTERS
[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
659 static const int COUNT_OF_LETTERS
= sizeof(LETTERS
)/sizeof(LETTERS
[0]) - 1;
660 sRandStr
.Append( sPrefix
);
662 static sal_uInt64 value
;
663 char buffer
[RAND_NAME_LENGTH
];
669 osl_getSystemTime( &tv
);
670 oslProcessInfo proInfo
;
671 osl_getProcessInfo( 0 , osl_Process_IDENTIFIER
, &proInfo
);
673 value
+= ((sal_uInt64
) ( tv
.Nanosec
/ 1000 ) << 16) ^ ( tv
.Nanosec
/ 1000 ) ^ proInfo
.Ident
;
677 for (i
= 0; i
< RAND_NAME_LENGTH
; i
++)
679 buffer
[i
] = LETTERS
[v
% COUNT_OF_LETTERS
];
680 v
/= COUNT_OF_LETTERS
;
683 sRandStr
.Append( buffer
, RAND_NAME_LENGTH
);
684 sRandStr
.Append( sPostfix
);
687 void Export::getRandomName( ByteString
& sRandStr
)
689 const ByteString sEmpty
;
690 getRandomName( sEmpty
, sRandStr
, sEmpty
);
693 /*****************************************************************************/
694 DirEntry
Export::GetTempFile()
695 /*****************************************************************************/
697 #if defined(WNT) || defined(OS2)
698 String
sTempDir( Export::GetEnv( "TEMP" ), RTL_TEXTENCODING_ASCII_US
);
700 String
sTempDir( String::CreateFromAscii( "/tmp" ));
702 rtl::OUString
* sTempFilename
= new rtl::OUString();
704 // Create a temp file
705 int nRC
= osl::FileBase::createTempFile( 0 , 0 , sTempFilename
);
706 if( nRC
) printf(" osl::FileBase::createTempFile RC = %d",nRC
);
708 String
strTmp( *sTempFilename
);
710 INetURLObject::DecodeMechanism eMechanism
= INetURLObject::DECODE_TO_IURI
;
711 String sDecodedStr
= INetURLObject::decode( strTmp
, '%' , eMechanism
);
712 ByteString
sTmp( sDecodedStr
, RTL_TEXTENCODING_UTF8
);
714 #if defined(WNT) || defined(OS2)
715 sTmp
.SearchAndReplace("file:///","");
716 sTmp
.SearchAndReplaceAll('/','\\');
718 // Set file permission to 644
719 const sal_uInt64 nPerm
= osl_File_Attribute_OwnRead
| osl_File_Attribute_OwnWrite
|
720 osl_File_Attribute_GrpRead
| osl_File_Attribute_OthRead
;
722 nRC
= osl::File::setAttributes( *sTempFilename
, nPerm
);
723 if( nRC
) printf(" osl::File::setAttributes RC = %d",nRC
);
725 sTmp
.SearchAndReplace("file://","");
727 DirEntry
aDirEntry( sTmp
);
728 delete sTempFilename
;