1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_l10ntools.hxx"
26 #include <stdio.h>
27 #include <tools/fsys.hxx>
28 #include "export.hxx"
29 #include "utf8conv.hxx"
30 #include <iostream>
31
32 using namespace std;
33
34 namespace
35 {
lcl_NormalizeFilename(const::rtl::OString & rFilename)36 static ::rtl::OString lcl_NormalizeFilename(const ::rtl::OString& rFilename)
37 {
38 return rFilename.copy(
39 ::std::max(
40 rFilename.lastIndexOf( "\\" ),
41 rFilename.lastIndexOf( "/" ))+1);
42 };
43 }
44
45 extern void ConvertHalfwitdhToFullwidth( String& rString );
46
47 //
48 // class PFormEntrys
49 //
50
Dump()51 ByteString PFormEntrys::Dump()
52 {
53 ByteString sRet( "PFormEntrys\n" );
54 ByteString a("sText");
55 if(sText.size())
56 Export::DumpMap(a , sText);
57 return sRet;
58 }
59
GetTransex3Text(ByteString & rReturn,sal_uInt16 nTyp,const ByteString & nLangIndex,sal_Bool bDel)60 sal_Bool PFormEntrys::GetTransex3Text( ByteString &rReturn,
61 sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel )
62 {
63 sal_Bool rc = GetText( rReturn , nTyp , nLangIndex , bDel );
64 ByteString test( rReturn );
65 for( sal_uInt16 idx = 0; idx < rReturn.Len(); idx++ )
66 {
67 if( rReturn.GetChar( idx ) == '\"' && ( idx >= 1 ) && rReturn.GetChar( idx-1 ) == '\\' )
68 {
69 rReturn.Erase( idx-1 , 1 );
70 }
71 }
72 //if( !rReturn.Equals( test ) )
73 // printf("*CHANGED******************\n%s\n%s\n",test.GetBuffer(),rReturn.GetBuffer());
74 return rc;
75 }
76 /*****************************************************************************/
GetText(ByteString & rReturn,sal_uInt16 nTyp,const ByteString & nLangIndex,sal_Bool bDel)77 sal_Bool PFormEntrys::GetText( ByteString &rReturn,
78 sal_uInt16 nTyp, const ByteString &nLangIndex, sal_Bool bDel )
79 {
80
81 sal_Bool bReturn=sal_True;
82 switch ( nTyp ) {
83 case STRING_TYP_TEXT :
84 rReturn = sText[ nLangIndex ];
85 if ( bDel )
86 sText[ nLangIndex ] = "";
87 bReturn = bTextFirst[ nLangIndex ];
88 bTextFirst[ nLangIndex ] = sal_False;
89 break;
90 case STRING_TYP_HELPTEXT :
91 rReturn = sHelpText;
92 break;
93 case STRING_TYP_QUICKHELPTEXT :
94 rReturn = sQuickHelpText[ nLangIndex ];
95 if ( bDel )
96 sQuickHelpText[ nLangIndex ] = "";
97 bReturn = bQuickHelpTextFirst[ nLangIndex ];
98 bQuickHelpTextFirst[ nLangIndex ] = sal_False;
99 break;
100 case STRING_TYP_TITLE :
101 rReturn = sTitle[ nLangIndex ];
102 if ( bDel )
103 sTitle[ nLangIndex ] = "";
104 bReturn = bTitleFirst[ nLangIndex ];
105 bTitleFirst[ nLangIndex ] = sal_False;
106 break;
107 }
108 return bReturn;
109 }
110
111
112 //
113 // class MergeData
114 //
115
~MergeData()116 MergeData::~MergeData()
117 {
118 }
119
GetPFormEntrys(ResData *)120 PFormEntrys* MergeData::GetPFormEntrys(ResData*)
121 {
122 if( aMap.find( ByteString("HACK") ) != aMap.end() )
123 return aMap[ ByteString("HACK") ];
124 return NULL;
125 }
126
Insert(const ByteString &,PFormEntrys * pfEntrys)127 void MergeData::Insert(const ByteString&, PFormEntrys* pfEntrys )
128 {
129 aMap.insert( PFormEntrysHashMap::value_type( ByteString("HACK") , pfEntrys ) );
130 }
131
Dump()132 ByteString MergeData::Dump(){
133 ByteString sRet( "MergeData\n" );
134
135 printf("MergeData sTyp = %s , sGid = %s , sLid =%s , sFilename = %s\n",sTyp.GetBuffer(),sGID.GetBuffer(),sLID.GetBuffer(), sFilename.GetBuffer() );
136
137 PFormEntrysHashMap::const_iterator idbg;
138 for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg )
139 {
140 printf("aMap[ %s ] = " ,idbg->first.GetBuffer());
141 ( (PFormEntrys*)(idbg->second) )->Dump();
142 printf("\n");
143 }
144 printf("\n");
145 return sRet;
146 }
147
GetPFObject(const ByteString & rPFO)148 PFormEntrys* MergeData::GetPFObject( const ByteString& rPFO ){
149 if( aMap.find( ByteString("HACK") ) != aMap.end() )
150 return aMap[ rPFO ];
151 return NULL;
152 }
153
154
InsertEntry(const ByteString & rPForm)155 PFormEntrys *MergeData::InsertEntry( const ByteString &rPForm )
156 {
157 PFormEntrys* pFEntrys = new PFormEntrys( rPForm );
158 aMap.insert( PFormEntrysHashMap::value_type( rPForm , pFEntrys ) );
159 return pFEntrys;
160 }
161
operator ==(ResData * pData)162 sal_Bool MergeData::operator==( ResData *pData )
163 {
164 ByteString sResTyp_upper( pData->sResTyp );
165 sResTyp_upper.ToUpperAscii();
166 ByteString sTyp_upper( sTyp );
167 sTyp_upper.ToUpperAscii();
168
169 return (( pData->sId == sLID ) &&
170 ( pData->sGId == sGID ) &&
171 ( sResTyp_upper == sTyp_upper )
172 );
173 }
174
175 //
176 // class MergeDataFile
177 //
178
179 #define FFORMAT_UNKNOWN 0x0000
180 #define FFORMAT_NEW 0x0001
181 #define FFORMAT_OLD 0x0002
182
183
MergeDataFile(const ByteString & rFileName,const ByteString & sFile,sal_Bool bErrLog,CharSet aCharSet,bool bCaseSensitive)184 MergeDataFile::MergeDataFile(
185 const ByteString &rFileName,
186 const ByteString& sFile,
187 sal_Bool bErrLog,
188 CharSet aCharSet,
189 bool bCaseSensitive)
190 : bErrorLog( bErrLog )
191 {
192 SvFileStream aInputStream( String( rFileName, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_READ );
193 aInputStream.SetStreamCharSet( aCharSet );
194 ByteString sLine;
195 const ByteString sHACK("HACK");
196 const ::rtl::OString sFileNormalized(lcl_NormalizeFilename(sFile));
197 const bool isFileEmpty = sFileNormalized.getLength();
198
199 if( !aInputStream.IsOpen() )
200 {
201 printf("Warning : Can't open %s\n", rFileName.GetBuffer());
202 return;
203 }
204 while ( !aInputStream.IsEof())
205 {
206 xub_StrLen nToks;
207 aInputStream.ReadLine( sLine );
208 sLine = sLine.Convert( RTL_TEXTENCODING_MS_1252, aCharSet );
209
210 nToks = sLine.GetTokenCount( '\t' );
211 if ( nToks == 15 )
212 {
213 // Skip all wrong filenames
214 const ::rtl::OString filename = lcl_NormalizeFilename(sLine.GetToken( 1 , '\t' ));
215 if(isFileEmpty || sFileNormalized.equals("") || (!isFileEmpty && filename.equals(sFileNormalized)) )
216 {
217 xub_StrLen rIdx = 0;
218 const ByteString sTYP = sLine.GetToken( 3, '\t', rIdx );
219 const ByteString sGID = sLine.GetToken( 0, '\t', rIdx ); // 4
220 const ByteString sLID = sLine.GetToken( 0, '\t', rIdx ); // 5
221 ByteString sPFO = sLine.GetToken( 1, '\t', rIdx ); // 7
222 sPFO = sHACK;
223 ByteString nLANG = sLine.GetToken( 1, '\t', rIdx ); // 9
224 nLANG.EraseLeadingAndTrailingChars();
225 const ByteString sTEXT = sLine.GetToken( 0, '\t', rIdx ); // 10
226 const ByteString sQHTEXT = sLine.GetToken( 1, '\t', rIdx ); // 12
227 const ByteString sTITLE = sLine.GetToken( 0, '\t', rIdx ); // 13
228
229
230 #ifdef MERGE_SOURCE_LANGUAGES
231 if( true )
232 #else
233 if( !nLANG.EqualsIgnoreCaseAscii("en-US") )
234 #endif
235 {
236 aLanguageSet.insert(nLANG);
237 InsertEntry( sTYP, sGID, sLID, sPFO, nLANG, sTEXT, sQHTEXT, sTITLE, filename, bCaseSensitive );
238 }
239 }
240 }
241 else if ( nToks == 10 )
242 {
243 printf("ERROR: File format is obsolete and no longer supported!\n");
244 }
245 }
246 aInputStream.Close();
247 }
248
~MergeDataFile()249 MergeDataFile::~MergeDataFile()
250 {
251 }
252
Dump()253 ByteString MergeDataFile::Dump(){
254 ByteString sRet( "MergeDataFile\n" );
255
256 printf("MergeDataFile\n");
257 MergeDataHashMap::const_iterator idbg;
258 for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg )
259 {
260 printf("aMap[ %s ] = ",idbg->first.GetBuffer());
261 ((MergeData*) (idbg->second))->Dump();
262 printf("\n");
263 }
264 printf("\n");
265 return sRet;
266 }
267
WriteError(const ByteString & rLine)268 void MergeDataFile::WriteError( const ByteString &rLine )
269 {
270 if ( bErrorLog )
271 {
272 if ( !aErrLog.IsOpen())
273 aErrLog.Open( String( sErrorLog, RTL_TEXTENCODING_ASCII_US ), STREAM_STD_WRITE | STREAM_TRUNC );
274 aErrLog.WriteLine( rLine );
275 }
276 else
277 fprintf( stderr, "%s\n", rLine.GetBuffer());
278 }
279
GetLanguages()280 std::vector<ByteString> MergeDataFile::GetLanguages(){
281 return std::vector<ByteString>(aLanguageSet.begin(),aLanguageSet.end());
282 }
283
GetMergeData(ResData * pResData,bool bCaseSensitive)284 MergeData *MergeDataFile::GetMergeData( ResData *pResData , bool bCaseSensitive )
285 {
286 ByteString sOldG = pResData->sGId;
287 ByteString sOldL = pResData->sId;
288 ByteString sGID = pResData->sGId;
289 ByteString sLID;
290 if(!sGID.Len())
291 sGID = pResData->sId;
292 else
293 sLID = pResData->sId;
294 pResData->sGId = sGID;
295 pResData->sId = sLID;
296
297 ByteString sKey = CreateKey( pResData->sResTyp , pResData->sGId , pResData->sId , pResData->sFilename , bCaseSensitive );
298
299 if(aMap.find( sKey ) != aMap.end())
300 {
301 pResData->sGId = sOldG;
302 pResData->sId = sOldL;
303 return aMap[ sKey ];
304 }
305 pResData->sGId = sOldG;
306 pResData->sId = sOldL;
307 return NULL;
308 }
309
310
GetPFormEntrys(ResData * pResData)311 PFormEntrys *MergeDataFile::GetPFormEntrys( ResData *pResData )
312 {
313 // search for requested PFormEntrys
314 MergeData *pData = GetMergeData( pResData );
315 if ( pData )
316 return pData->GetPFormEntrys( pResData );
317 return NULL;
318 }
319
GetPFormEntrysCaseSensitive(ResData * pResData)320 PFormEntrys *MergeDataFile::GetPFormEntrysCaseSensitive( ResData *pResData )
321 {
322 // search for requested PFormEntrys
323 MergeData *pData = GetMergeData( pResData , true );
324 if ( pData )
325 return pData->GetPFormEntrys( pResData );
326 return NULL;
327 }
328
InsertEntry(const ByteString & rTYP,const ByteString & rGID,const ByteString & rLID,const ByteString & rPFO,const ByteString & nLANG,const ByteString & rTEXT,const ByteString & rQHTEXT,const ByteString & rTITLE,const ByteString & rInFilename,bool bCaseSensitive)329 void MergeDataFile::InsertEntry(
330 const ByteString &rTYP, const ByteString &rGID,
331 const ByteString &rLID, const ByteString &rPFO,
332 const ByteString &nLANG, const ByteString &rTEXT,
333 const ByteString &rQHTEXT, const ByteString &rTITLE ,
334 const ByteString &rInFilename , bool bCaseSensitive
335 )
336 {
337 MergeData *pData;
338
339 // search for MergeData
340 ByteString sKey = CreateKey( rTYP , rGID , rLID , rInFilename , bCaseSensitive );
341 MergeDataHashMap::const_iterator mit;
342 mit = aMap.find( sKey );
343 if( mit != aMap.end() )
344 {
345 pData = mit->second;
346 }
347 else
348 {
349 pData = new MergeData( rTYP, rGID, rLID, rInFilename );
350 aMap.insert( MergeDataHashMap::value_type( sKey, pData ) );
351 }
352
353 PFormEntrys *pFEntrys = 0;
354
355 // search for PFormEntrys
356 pFEntrys = pData->GetPFObject( rPFO );
357 if( !pFEntrys )
358 {
359 // create new PFormEntrys, cause no one exists with current properties
360 pFEntrys = new PFormEntrys( rPFO );
361 pData->Insert( rPFO , pFEntrys );
362 }
363
364 // finally insert the cur string
365 pFEntrys->InsertEntry( nLANG , rTEXT, rQHTEXT, rTITLE );
366 }
367
CreateKey(const ByteString & rTYP,const ByteString & rGID,const ByteString & rLID,const ByteString & rFilename,bool bCaseSensitive)368 ByteString MergeDataFile::CreateKey( const ByteString& rTYP , const ByteString& rGID , const ByteString& rLID , const ByteString& rFilename , bool bCaseSensitive )
369 {
370 static const ::rtl::OString sStroke('-');
371 ::rtl::OString sKey( rTYP );
372 sKey += sStroke;
373 sKey += rGID;
374 sKey += sStroke;
375 sKey += rLID;
376 sKey += sStroke;
377 sKey += lcl_NormalizeFilename(rFilename);
378 OSL_TRACE("created key: %s", sKey.getStr());
379 if(bCaseSensitive)
380 return sKey; // officecfg case sensitive identifier
381 return sKey.toAsciiUpperCase();
382 }
383