Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : */
9 :
10 : #include <cstdlib>
11 : #include <cassert>
12 : #include <iostream>
13 : #include <fstream>
14 : #include <iomanip>
15 :
16 : #include "export.hxx"
17 : #include "common.hxx"
18 : #include "propmerge.hxx"
19 :
20 : namespace
21 : {
22 : //Write out an sdf line
23 0 : static void lcl_WriteSDF(
24 : std::ofstream &aSDFStream, const OString& rText, const OString& rPrj,
25 : const OString& rActFileName, const OString& rID )
26 : {
27 0 : OString sOutput( rPrj ); sOutput += "\t";
28 0 : sOutput += rActFileName;
29 0 : sOutput += "\t0\tproperty\t";
30 0 : sOutput += rID; sOutput += "\t\t\t\t0\ten-US\t";
31 0 : sOutput += rText; sOutput += "\t\t\t\t";
32 0 : aSDFStream << sOutput.getStr() << std::endl;
33 0 : }
34 :
35 : //Find ascii escaped unicode
36 0 : static sal_Int32 lcl_IndexOfUnicode(
37 : const OString& rSource, const sal_Int32 nFrom = 0 )
38 : {
39 0 : const OString sHexDigits = "0123456789abcdefABCDEF";
40 0 : sal_Int32 nIndex = rSource.indexOf( "\\u", nFrom );
41 0 : if( nIndex == -1 )
42 : {
43 0 : return -1;
44 : }
45 0 : bool bIsUnicode = true;
46 0 : for( short nDist = 2; nDist <= 5; ++nDist )
47 : {
48 0 : if( sHexDigits.indexOf( rSource[nIndex + nDist] ) == -1 )
49 : {
50 0 : bIsUnicode = false;
51 : }
52 : }
53 0 : return bIsUnicode ? nIndex : -1;
54 : }
55 :
56 : //Convert ascii escaped unicode to utf-8
57 0 : static OString lcl_ConvertToUTF8( const OString& rText )
58 : {
59 0 : OString sResult = rText;
60 0 : sal_Int32 nIndex = lcl_IndexOfUnicode( sResult );
61 0 : while( nIndex != -1 && nIndex < rText.getLength() )
62 : {
63 0 : const OString sHex = sResult.copy( nIndex + 2, 4 );
64 : const sal_Unicode cDec =
65 0 : static_cast<sal_Unicode>( strtol( sHex.getStr(), NULL, 16 ) );
66 : const OString sNewChar =
67 0 : OString( &cDec, 1, RTL_TEXTENCODING_UTF8 );
68 0 : sResult = sResult.replaceAll( "\\u" + sHex, sNewChar );
69 0 : nIndex = lcl_IndexOfUnicode( sResult, nIndex );
70 0 : }
71 0 : return sResult;
72 : }
73 :
74 : //Escape unicode characters
75 0 : static void lcl_PrintJavaStyle( const OString& rText, std::ofstream &rOfstream )
76 : {
77 : const OUString sTemp =
78 0 : OStringToOUString( rText, RTL_TEXTENCODING_UTF8 );
79 0 : for ( sal_Int32 nIndex = 0; nIndex < sTemp.getLength(); ++nIndex )
80 : {
81 0 : sal_Unicode cUniCode = sTemp[nIndex];
82 0 : if( cUniCode < 128 )
83 : {
84 0 : rOfstream << static_cast<char>( cUniCode );
85 : }
86 : else
87 : {
88 : rOfstream
89 0 : << "\\u"
90 0 : << std::setfill('0') << std::setw(2) << std::uppercase
91 0 : << std::hex << (cUniCode >> 8) << (cUniCode & 0xFF);
92 : }
93 0 : }
94 0 : }
95 : }
96 :
97 : //Open source file and store its lines
98 0 : PropParser::PropParser(
99 : const OString& rInputFile, const OString& rLang,
100 : const bool bMergeMode )
101 : : m_vLines( std::vector<OString>() )
102 : , m_sSource( rInputFile )
103 : , m_sLang( rLang )
104 0 : , m_bIsInitialized( false )
105 : {
106 0 : std::ifstream aIfstream( m_sSource.getStr() );
107 0 : if( aIfstream.is_open() )
108 : {
109 0 : std::string s;
110 0 : std::getline( aIfstream, s );
111 0 : while( !aIfstream.eof() )
112 : {
113 0 : OString sLine( s.data(), s.length() );
114 0 : if( bMergeMode ||
115 0 : ( !sLine.startsWith(" *") && !sLine.startsWith("/*") ) )
116 : {
117 0 : m_vLines.push_back( sLine );
118 : }
119 0 : std::getline( aIfstream, s );
120 0 : }
121 : }
122 : else
123 : {
124 : std::cerr
125 0 : << "Propex error: Cannot open source file: "
126 0 : << m_sSource.getStr() << std::endl;
127 0 : return;
128 : }
129 0 : m_bIsInitialized = true;
130 : }
131 :
132 0 : PropParser::~PropParser()
133 : {
134 0 : }
135 :
136 : //Extract strings form source file
137 0 : void PropParser::Extract(
138 : const OString& rSDFFile, const OString& rPrj, const OString& rRoot )
139 : {
140 : assert( m_bIsInitialized );
141 : std::ofstream aSDFStream(
142 0 : rSDFFile.getStr(), std::ios_base::out | std::ios_base::trunc );
143 0 : if( !aSDFStream.is_open() )
144 : {
145 : std::cerr
146 0 : << "Propex error: Cannot open sdffile for extract: "
147 0 : << rSDFFile.getStr() << std::endl;
148 0 : return;
149 : }
150 :
151 0 : for( unsigned nIndex = 0; nIndex < m_vLines.size(); ++nIndex )
152 : {
153 0 : const OString sLine = m_vLines[nIndex];
154 0 : const sal_Int32 nEqualSign = sLine.indexOf('=');
155 0 : if( nEqualSign != -1 )
156 : {
157 : lcl_WriteSDF(
158 : aSDFStream,
159 : lcl_ConvertToUTF8( sLine.copy( nEqualSign + 1 ).trim() ),//Text
160 : rPrj,
161 : common::pathnameToken(
162 : m_sSource.getStr(), rRoot.getStr()), //FileName
163 0 : sLine.copy( 0, nEqualSign ).trim() ); //ID
164 : }
165 0 : }
166 :
167 0 : aSDFStream.close();
168 : }
169 :
170 : //Merge strings to source file
171 0 : void PropParser::Merge( const OString &rMergeSrc, const OString &rDestinationFile )
172 : {
173 : assert( m_bIsInitialized );
174 : std::ofstream aDestination(
175 0 : rDestinationFile.getStr(), std::ios_base::out | std::ios_base::trunc );
176 0 : if( !aDestination.is_open() ) {
177 : std::cerr
178 0 : << "Propex error: Cannot open source file for merge: "
179 0 : << rDestinationFile.getStr() << std::endl;
180 : return;
181 : }
182 :
183 : MergeDataFile aMergeDataFile(
184 0 : rMergeSrc, m_sSource, false, m_sLang == "qtz" );
185 :
186 0 : const std::vector<OString> vLanguages = aMergeDataFile.GetLanguages();
187 0 : if( m_sLang != "qtz" && vLanguages.size()>=2 &&
188 0 : vLanguages[vLanguages[0]!="qtz" ? 0 : 1] != m_sLang )
189 : {
190 : std::cerr
191 0 : << "Propex error: given language conflicts with "
192 0 : << "language of Mergedata file: "
193 0 : << m_sLang.getStr() << " - "
194 0 : << vLanguages[vLanguages[0]!="qtz" ? 0 : 1].getStr() << std::endl;
195 : return;
196 : }
197 :
198 0 : for( unsigned nIndex = 0; nIndex < m_vLines.size(); ++nIndex )
199 : {
200 0 : const OString sLine = m_vLines[nIndex];
201 0 : const sal_Int32 nEqualSign = sLine.indexOf('=');
202 0 : if( !sLine.startsWith(" *") && !sLine.startsWith("/*") &&
203 : nEqualSign != -1 )
204 : {
205 0 : const OString sID( sLine.copy( 0, sLine.indexOf("=") ).trim() );
206 0 : ResData aResData( "", sID , m_sSource );
207 0 : aResData.sResTyp = "property";
208 0 : PFormEntrys* pEntrys = aMergeDataFile.GetPFormEntrys( &aResData );
209 0 : if( pEntrys )
210 : {
211 0 : OString sNewText;
212 0 : pEntrys->GetText( sNewText, STRING_TYP_TEXT, m_sLang );
213 0 : aDestination << OString(sID + "=").getStr();
214 0 : lcl_PrintJavaStyle( sNewText, aDestination );
215 0 : aDestination << std::endl;
216 : }
217 : else
218 : {
219 0 : aDestination << sLine.getStr() << std::endl;
220 0 : }
221 : }
222 : else
223 : {
224 0 : aDestination << sLine.getStr() << std::endl;
225 : }
226 0 : }
227 0 : aDestination.close();
228 0 : }
229 :
230 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|