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)
92 0 : << std::setfill('0') << std::setw(2) << std::uppercase
93 0 : << std::hex << (cUniCode & 0xFF);
94 : }
95 0 : }
96 0 : }
97 : }
98 :
99 : //Open source file and store its lines
100 0 : PropParser::PropParser(
101 : const OString& rInputFile, const OString& rLang,
102 : const bool bMergeMode )
103 : : m_vLines( std::vector<OString>() )
104 : , m_sSource( rInputFile )
105 : , m_sLang( rLang )
106 0 : , m_bIsInitialized( false )
107 : {
108 0 : std::ifstream aIfstream( m_sSource.getStr() );
109 0 : if( aIfstream.is_open() )
110 : {
111 0 : std::string s;
112 0 : std::getline( aIfstream, s );
113 0 : while( !aIfstream.eof() )
114 : {
115 0 : OString sLine( s.data(), s.length() );
116 0 : if( bMergeMode ||
117 0 : ( !sLine.startsWith(" *") && !sLine.startsWith("/*") ) )
118 : {
119 0 : m_vLines.push_back( sLine );
120 : }
121 0 : std::getline( aIfstream, s );
122 0 : }
123 : }
124 : else
125 : {
126 : std::cerr
127 0 : << "Propex error: Cannot open source file: "
128 0 : << m_sSource.getStr() << std::endl;
129 0 : return;
130 : }
131 0 : m_bIsInitialized = true;
132 : }
133 :
134 0 : PropParser::~PropParser()
135 : {
136 0 : }
137 :
138 : //Extract strings form source file
139 0 : void PropParser::Extract(
140 : const OString& rSDFFile, const OString& rPrj, const OString& rRoot )
141 : {
142 : assert( m_bIsInitialized );
143 : std::ofstream aSDFStream(
144 0 : rSDFFile.getStr(), std::ios_base::out | std::ios_base::trunc );
145 0 : if( !aSDFStream.is_open() )
146 : {
147 : std::cerr
148 0 : << "Propex error: Cannot open sdffile for extract: "
149 0 : << rSDFFile.getStr() << std::endl;
150 0 : return;
151 : }
152 :
153 0 : for( unsigned nIndex = 0; nIndex < m_vLines.size(); ++nIndex )
154 : {
155 0 : const OString sLine = m_vLines[nIndex];
156 0 : const sal_Int32 nEqualSign = sLine.indexOf('=');
157 0 : if( nEqualSign != -1 )
158 : {
159 : lcl_WriteSDF(
160 : aSDFStream,
161 : lcl_ConvertToUTF8( sLine.copy( nEqualSign + 1 ).trim() ),//Text
162 : rPrj,
163 : common::pathnameToken(
164 : m_sSource.getStr(), rRoot.getStr()), //FileName
165 0 : sLine.copy( 0, nEqualSign ).trim() ); //ID
166 : }
167 0 : }
168 :
169 0 : aSDFStream.close();
170 : }
171 :
172 : //Merge strings to source file
173 0 : void PropParser::Merge( const OString &rMergeSrc, const OString &rDestinationFile )
174 : {
175 : assert( m_bIsInitialized );
176 : std::ofstream aDestination(
177 0 : rDestinationFile.getStr(), std::ios_base::out | std::ios_base::trunc );
178 0 : if( !aDestination.is_open() ) {
179 : std::cerr
180 0 : << "Propex error: Cannot open source file for merge: "
181 0 : << rDestinationFile.getStr() << std::endl;
182 : return;
183 : }
184 :
185 : MergeDataFile aMergeDataFile(
186 0 : rMergeSrc, m_sSource, false, m_sLang == "qtz" );
187 :
188 0 : const std::vector<OString> vLanguages = aMergeDataFile.GetLanguages();
189 0 : if( m_sLang != "qtz" && vLanguages.size()>=2 &&
190 0 : vLanguages[vLanguages[0]!="qtz" ? 0 : 1] != m_sLang )
191 : {
192 : std::cerr
193 0 : << "Propex error: given language conflicts with "
194 0 : << "language of Mergedata file: "
195 0 : << m_sLang.getStr() << " - "
196 0 : << vLanguages[vLanguages[0]!="qtz" ? 0 : 1].getStr() << std::endl;
197 : return;
198 : }
199 :
200 0 : for( unsigned nIndex = 0; nIndex < m_vLines.size(); ++nIndex )
201 : {
202 0 : const OString sLine = m_vLines[nIndex];
203 0 : const sal_Int32 nEqualSign = sLine.indexOf('=');
204 0 : if( !sLine.startsWith(" *") && !sLine.startsWith("/*") &&
205 : nEqualSign != -1 )
206 : {
207 0 : const OString sID( sLine.copy( 0, sLine.indexOf("=") ).trim() );
208 0 : ResData aResData( "", sID , m_sSource );
209 0 : aResData.sResTyp = "property";
210 0 : PFormEntrys* pEntrys = aMergeDataFile.GetPFormEntrys( &aResData );
211 0 : if( pEntrys )
212 : {
213 0 : OString sNewText;
214 0 : pEntrys->GetText( sNewText, STRING_TYP_TEXT, m_sLang );
215 0 : aDestination << OString(sID + "=").getStr();
216 0 : lcl_PrintJavaStyle( sNewText, aDestination );
217 0 : aDestination << std::endl;
218 : }
219 : else
220 : {
221 0 : aDestination << sLine.getStr() << std::endl;
222 0 : }
223 : }
224 : else
225 : {
226 0 : aDestination << sLine.getStr() << std::endl;
227 : }
228 0 : }
229 0 : aDestination.close();
230 0 : }
231 :
232 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|