/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_l10ntools.hxx" #include // local includes #include "lngmerge.hxx" #include "utf8conv.hxx" #include using namespace std; // // class LngParser // /*****************************************************************************/ LngParser::LngParser( const ByteString &rLngFile, sal_Bool bUTF8, sal_Bool bULFFormat ) /*****************************************************************************/ : nError( LNG_OK ), pLines( NULL ), sSource( rLngFile ), bDBIsUTF8( bUTF8 ), bULF( bULFFormat ) { pLines = new LngLineList( 100, 100 ); DirEntry aEntry( String( sSource, RTL_TEXTENCODING_ASCII_US )); if ( aEntry.Exists()) { SvFileStream aStream( String( sSource, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ ); if ( aStream.IsOpen()) { ByteString sLine; bool bFirstLine = true; while ( !aStream.IsEof()) { aStream.ReadLine( sLine ); if( bFirstLine ){ // Always remove UTF8 BOM from the first line Export::RemoveUTF8ByteOrderMarker( sLine ); bFirstLine = false; } pLines->Insert( new ByteString( sLine ), LIST_APPEND ); } } else nError = LNG_COULD_NOT_OPEN; } else nError = LNG_FILE_NOTFOUND; } /*****************************************************************************/ LngParser::~LngParser() /*****************************************************************************/ { for ( sal_uLong i = 0; i < pLines->Count(); i++ ) delete pLines->GetObject( i ); delete pLines; } /*****************************************************************************/ void LngParser::FillInFallbacks( ByteStringHashMap Text ) /*****************************************************************************/ { ByteString sCur; for( unsigned int n = 0; n < aLanguages.size(); n++ ){ sCur = aLanguages[ n ]; if( Export::isAllowed( sCur ) ){ ByteString sFallbackLang = Export::GetFallbackLanguage( sCur ); if( sFallbackLang.Len() ){ Text[ sCur ] = Text[ sFallbackLang ]; } } } } /*****************************************************************************/ sal_Bool LngParser::CreateSDF( const ByteString &rSDFFile, const ByteString &rPrj, const ByteString &rRoot ) /*****************************************************************************/ { Export::InitLanguages( false ); aLanguages = Export::GetLanguages(); SvFileStream aSDFStream( String( rSDFFile, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC ); if ( !aSDFStream.IsOpen()) { nError = SDF_COULD_NOT_OPEN; } aSDFStream.SetStreamCharSet( RTL_TEXTENCODING_UTF8 ); nError = SDF_OK; DirEntry aEntry( String( sSource, RTL_TEXTENCODING_ASCII_US )); aEntry.ToAbs(); String sFullEntry = aEntry.GetFull(); aEntry += DirEntry( String( "..", RTL_TEXTENCODING_ASCII_US )); aEntry += DirEntry( rRoot ); ByteString sPrjEntry( aEntry.GetFull(), gsl_getSystemTextEncoding()); ByteString sActFileName( sFullEntry.Copy( sPrjEntry.Len() + 1 ), gsl_getSystemTextEncoding()); sActFileName.SearchAndReplaceAll( "/", "\\" ); sal_uLong nPos = 0; sal_Bool bStart = true; ByteString sGroup; ByteStringHashMap Text; ByteString sID; ByteString sLine; while( nPos < pLines->Count() ){ sLine = *pLines->GetObject( nPos++ ); while( nPos < pLines->Count() && !isNextGroup( sGroup , sLine ) ){ ReadLine( sLine , Text ); sID = sGroup; sLine = *pLines->GetObject( nPos++ ); }; if( bStart ){ bStart = false; sID = sGroup; } else { WriteSDF( aSDFStream , Text , rPrj , rRoot , sActFileName , sID ); } } aSDFStream.Close(); return true; } void LngParser::WriteSDF( SvFileStream &aSDFStream , ByteStringHashMap &rText_inout , const ByteString &rPrj , const ByteString &rRoot , const ByteString &sActFileName , const ByteString &sID ) { sal_Bool bExport = true; if ( bExport ) { ByteString sTimeStamp( Export::GetTimeStamp()); ByteString sCur; FillInFallbacks( rText_inout ); for( unsigned int n = 0; n < aLanguages.size(); n++ ){ sCur = aLanguages[ n ]; ByteString sAct = rText_inout[ sCur ]; if ( !sAct.Len() && sCur.Len() ) sAct = rText_inout[ ByteString("en-US") ]; ByteString sOutput( rPrj ); sOutput += "\t"; if ( rRoot.Len()) sOutput += sActFileName; sOutput += "\t0\t"; sOutput += "LngText\t"; sOutput += sID; sOutput += "\t\t\t\t0\t"; sOutput += sCur; sOutput += "\t"; sOutput += sAct; sOutput += "\t\t\t\t"; sOutput += sTimeStamp; //if( !sCur.EqualsIgnoreCaseAscii("de") ||( sCur.EqualsIgnoreCaseAscii("de") && !Export::isMergingGermanAllowed( rPrj ) ) ) aSDFStream.WriteLine( sOutput ); } } } bool LngParser::isNextGroup( ByteString &sGroup_out , ByteString &sLine_in ){ sLine_in.EraseLeadingChars( ' ' ); sLine_in.EraseTrailingChars( ' ' ); if (( sLine_in.GetChar( 0 ) == '[' ) && ( sLine_in.GetChar( sLine_in.Len() - 1 ) == ']' )){ sGroup_out = sLine_in.GetToken( 1, '[' ).GetToken( 0, ']' ); sGroup_out.EraseLeadingChars( ' ' ); sGroup_out.EraseTrailingChars( ' ' ); return true; } return false; } void LngParser::ReadLine( const ByteString &sLine_in , ByteStringHashMap &rText_inout){ //printf("sLine -> '%s'\n",sLine_in.GetBuffer()); ByteString sLang = sLine_in.GetToken( 0, '=' ); sLang.EraseLeadingChars( ' ' ); sLang.EraseTrailingChars( ' ' ); ByteString sText = sLine_in.GetToken( 1, '\"' ).GetToken( 0, '\"' ); if( sLang.Len() ) rText_inout[ sLang ] = sText; } /*****************************************************************************/ sal_Bool LngParser::Merge( const ByteString &rSDFFile, const ByteString &rDestinationFile , const ByteString& rPrj ) /*****************************************************************************/ { (void) rPrj; Export::InitLanguages( true ); SvFileStream aDestination( String( rDestinationFile, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC ); if ( !aDestination.IsOpen()) { nError = LNG_COULD_NOT_OPEN; } nError = LNG_OK; // MergeDataFile( const ByteString &rFileName, const ByteString& rFile , sal_Bool bErrLog, CharSet aCharSet, sal_Bool bUTF8 ); MergeDataFile aMergeDataFile( rSDFFile, sSource , sal_False, RTL_TEXTENCODING_MS_1252);//, bDBIsUTF8 ); ByteString sTmp( Export::sLanguages ); if( sTmp.ToUpperAscii().Equals("ALL") ) Export::SetLanguages( aMergeDataFile.GetLanguages() ); aLanguages = Export::GetLanguages(); sal_uLong nPos = 0; sal_Bool bGroup = sal_False; ByteString sGroup; // seek to next group while ( nPos < pLines->Count() && !bGroup ) { ByteString sLine( *pLines->GetObject( nPos )); sLine.EraseLeadingChars( ' ' ); sLine.EraseTrailingChars( ' ' ); if (( sLine.GetChar( 0 ) == '[' ) && ( sLine.GetChar( sLine.Len() - 1 ) == ']' )) { sGroup = sLine.GetToken( 1, '[' ).GetToken( 0, ']' ); sGroup.EraseLeadingChars( ' ' ); sGroup.EraseTrailingChars( ' ' ); bGroup = sal_True; } nPos ++; } while ( nPos < pLines->Count()) { ByteStringHashMap Text; ByteString sID( sGroup ); sal_uLong nLastLangPos = 0; ResData *pResData = new ResData( "", sID , sSource ); pResData->sResTyp = "LngText"; PFormEntrys *pEntrys = aMergeDataFile.GetPFormEntrys( pResData ); // read languages bGroup = sal_False; ByteString sLanguagesDone; while ( nPos < pLines->Count() && !bGroup ) { ByteString sLine( *pLines->GetObject( nPos )); sLine.EraseLeadingChars( ' ' ); sLine.EraseTrailingChars( ' ' ); if (( sLine.GetChar( 0 ) == '[' ) && ( sLine.GetChar( sLine.Len() - 1 ) == ']' )) { sGroup = sLine.GetToken( 1, '[' ).GetToken( 0, ']' ); sGroup.EraseLeadingChars( ' ' ); sGroup.EraseTrailingChars( ' ' ); bGroup = sal_True; nPos ++; sLanguagesDone = ""; } else if ( sLine.GetTokenCount( '=' ) > 1 ) { ByteString sLang = sLine.GetToken( 0, '=' ); sLang.EraseLeadingChars( ' ' ); sLang.EraseTrailingChars( ' ' ); ByteString sSearch( ";" ); sSearch += sLang; sSearch += ";"; if (( sLanguagesDone.Search( sSearch ) != STRING_NOTFOUND )) { pLines->Remove( nPos ); } if( bULF && pEntrys ) { // this is a valid text line ByteString sText = sLine.GetToken( 1, '\"' ).GetToken( 0, '\"' ); if( sLang.Len() ){ ByteString sNewText; pEntrys->GetText( sNewText, STRING_TYP_TEXT, sLang, sal_True ); if ( sNewText.Len()) { ByteString *pLine = pLines->GetObject( nPos ); ByteString sText1( sLang ); sText1 += " = \""; sText1 += sNewText; sText1 += "\""; *pLine = sText1; //} Text[ sLang ] = sNewText; } } nLastLangPos = nPos; nPos ++; sLanguagesDone += sSearch; } else { nLastLangPos = nPos; nPos ++; sLanguagesDone += sSearch; } } else nPos++; } ByteString sCur; if ( nLastLangPos ) { for( unsigned int n = 0; n < aLanguages.size(); n++ ){ sCur = aLanguages[ n ]; if( //( !sCur.EqualsIgnoreCaseAscii("de") || //( sCur.EqualsIgnoreCaseAscii("de") && Export::isMergingGermanAllowed( rPrj ) ) ) !sCur.EqualsIgnoreCaseAscii("en-US") && !Text[ sCur ].Len() && pEntrys ){ ByteString sNewText; pEntrys->GetText( sNewText, STRING_TYP_TEXT, sCur, sal_True ); if (( sNewText.Len()) && !(( sCur.Equals("x-comment") ) && ( sNewText == "-" ))) { ByteString sLine; sLine += sCur; sLine += " = \""; sLine += sNewText; sLine += "\""; nLastLangPos++; nPos++; pLines->Insert( new ByteString( sLine ), nLastLangPos ); } } } } delete pResData; } for ( sal_uLong i = 0; i < pLines->Count(); i++ ) aDestination.WriteLine( *pLines->GetObject( i )); aDestination.Close(); return sal_True; }