1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <rtl/ustring.hxx>
11 #include <o3tl/string_view.hxx>
18 #include <string_view>
22 #include <propmerge.hxx>
27 //Find ascii escaped unicode
28 sal_Int32
lcl_IndexOfUnicode(
29 std::string_view rSource
, const sal_Int32 nFrom
= 0 )
31 const OString sHexDigits
= "0123456789abcdefABCDEF";
32 size_t nIndex
= rSource
.find( "\\u", nFrom
);
33 if( nIndex
== std::string_view::npos
)
37 bool bIsUnicode
= true;
38 for( short nDist
= 2; nDist
<= 5; ++nDist
)
40 if( sHexDigits
.indexOf( rSource
[nIndex
+ nDist
] ) == -1 )
45 return bIsUnicode
? nIndex
: -1;
48 //Convert ascii escaped unicode to utf-8
49 OString
lcl_ConvertToUTF8( const OString
& rText
)
51 OString sResult
= rText
;
52 sal_Int32 nIndex
= lcl_IndexOfUnicode( sResult
);
53 while( nIndex
!= -1 && nIndex
< rText
.getLength() )
55 const OString sHex
= sResult
.copy( nIndex
+ 2, 4 );
56 const sal_Unicode cDec
=
57 static_cast<sal_Unicode
>( strtol( sHex
.getStr(), nullptr, 16 ) );
58 const OString
sNewChar( &cDec
, 1, RTL_TEXTENCODING_UTF8
);
59 sResult
= sResult
.replaceAll( "\\u" + sHex
, sNewChar
);
60 nIndex
= lcl_IndexOfUnicode( sResult
, nIndex
);
65 //Escape unicode characters
66 void lcl_PrintJavaStyle( std::string_view rText
, std::ofstream
&rOfstream
)
68 const OUString sTemp
=
69 OStringToOUString( rText
, RTL_TEXTENCODING_UTF8
);
70 for ( sal_Int32 nIndex
= 0; nIndex
< sTemp
.getLength(); ++nIndex
)
72 sal_Unicode cUniCode
= sTemp
[nIndex
];
75 rOfstream
<< static_cast<char>( cUniCode
);
81 << std::setfill('0') << std::setw(2) << std::uppercase
82 << std::hex
<< (cUniCode
>> 8)
83 << std::setfill('0') << std::setw(2) << std::uppercase
84 << std::hex
<< (cUniCode
& 0xFF);
90 //Open source file and store its lines
91 PropParser::PropParser(
92 OString _sInputFile
, OString _sLang
,
93 const bool bMergeMode
)
94 : m_sSource(std::move( _sInputFile
))
95 , m_sLang(std::move( _sLang
))
96 , m_bIsInitialized( false )
98 std::ifstream
aIfstream( m_sSource
.getStr() );
99 if( aIfstream
.is_open() )
102 std::getline( aIfstream
, s
);
103 while( !aIfstream
.eof() )
105 OString
sLine( s
.data(), s
.length() );
107 ( !sLine
.startsWith(" *") && !sLine
.startsWith("/*") ) )
109 m_vLines
.push_back( sLine
);
111 std::getline( aIfstream
, s
);
117 << "Propex error: Cannot open source file: "
118 << m_sSource
<< std::endl
;
121 m_bIsInitialized
= true;
124 PropParser::~PropParser()
128 //Extract strings form source file
129 void PropParser::Extract( const OString
& rPOFile
)
131 assert( m_bIsInitialized
);
132 PoOfstream
aPOStream( rPOFile
, PoOfstream::APP
);
133 if( !aPOStream
.isOpen() )
136 << "Propex error: Cannot open pofile for extract: "
137 << rPOFile
<< std::endl
;
141 for( size_t nIndex
= 0; nIndex
< m_vLines
.size(); ++nIndex
)
143 const OString sLine
= m_vLines
[nIndex
];
144 const sal_Int32 nEqualSign
= sLine
.indexOf('=');
145 if( nEqualSign
!= -1 )
147 std::string_view sID
= o3tl::trim(sLine
.subView( 0, nEqualSign
));
148 OString sText
= lcl_ConvertToUTF8( OString(o3tl::trim(sLine
.subView( nEqualSign
+ 1 ))) );
150 common::writePoEntry(
151 "Propex", aPOStream
, m_sSource
, "property",
152 OString(sID
), OString(), OString(), sText
);
159 //Merge strings to source file
160 void PropParser::Merge( const OString
&rMergeSrc
, const OString
&rDestinationFile
)
162 assert( m_bIsInitialized
);
163 std::ofstream
aDestination(
164 rDestinationFile
.getStr(), std::ios_base::out
| std::ios_base::trunc
);
165 if( !aDestination
.is_open() ) {
167 << "Propex error: Cannot open source file for merge: "
168 << rDestinationFile
<< std::endl
;
172 std::unique_ptr
<MergeDataFile
> pMergeDataFile
;
173 if( m_sLang
!= "qtz" )
175 pMergeDataFile
.reset( new MergeDataFile( rMergeSrc
, m_sSource
, false, false ) );
177 const std::vector
<OString
> vLanguages
= pMergeDataFile
->GetLanguages();
178 if( !vLanguages
.empty() && vLanguages
[0] != m_sLang
)
181 << ("Propex error: given language conflicts with language of"
184 << vLanguages
[0] << std::endl
;
189 for( size_t nIndex
= 0; nIndex
< m_vLines
.size(); ++nIndex
)
191 const OString sLine
= m_vLines
[nIndex
];
192 const sal_Int32 nEqualSign
= sLine
.indexOf('=');
193 if( !sLine
.startsWith(" *") && !sLine
.startsWith("/*") &&
196 const OString
sID( o3tl::trim(sLine
.subView( 0, sLine
.indexOf('=') )) );
197 ResData
aResData( sID
, m_sSource
);
198 aResData
.sResTyp
= "property";
200 if( m_sLang
== "qtz" )
202 const OString sOriginText
= lcl_ConvertToUTF8(OString(o3tl::trim(sLine
.subView( nEqualSign
+ 1 ))));
203 sNewText
= MergeEntrys::GetQTZText(aResData
, sOriginText
);
205 else if( pMergeDataFile
)
207 MergeEntrys
* pEntrys
= pMergeDataFile
->GetMergeEntrys( &aResData
);
210 pEntrys
->GetText( sNewText
, m_sLang
);
213 if( !sNewText
.isEmpty() )
215 aDestination
<< OString(sID
+ "=");
216 lcl_PrintJavaStyle( sNewText
, aDestination
);
217 aDestination
<< std::endl
;
221 aDestination
<< sLine
<< std::endl
;
226 aDestination
<< sLine
<< std::endl
;
229 aDestination
.close();
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */