SAGA API  v9.5
api_translator.cpp
Go to the documentation of this file.
1 /**********************************************************
2  * Version $Id$
3  *********************************************************/
4 
6 // //
7 // SAGA //
8 // //
9 // System for Automated Geoscientific Analyses //
10 // //
11 // Application Programming Interface //
12 // //
13 // Library: SAGA_API //
14 // //
15 //-------------------------------------------------------//
16 // //
17 // api_translator.cpp //
18 // //
19 // Copyright (C) 2005 by Olaf Conrad //
20 // //
21 //-------------------------------------------------------//
22 // //
23 // This file is part of 'SAGA - System for Automated //
24 // Geoscientific Analyses'. //
25 // //
26 // This library is free software; you can redistribute //
27 // it and/or modify it under the terms of the GNU Lesser //
28 // General Public License as published by the Free //
29 // Software Foundation, either version 2.1 of the //
30 // License, or (at your option) any later version. //
31 // //
32 // This library is distributed in the hope that it will //
33 // be useful, but WITHOUT ANY WARRANTY; without even the //
34 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
35 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
36 // License for more details. //
37 // //
38 // You should have received a copy of the GNU Lesser //
39 // General Public License along with this program; if //
40 // not, see <http://www.gnu.org/licenses/>. //
41 // //
42 //-------------------------------------------------------//
43 // //
44 // contact: Olaf Conrad //
45 // Institute of Geography //
46 // University of Goettingen //
47 // Goldschmidtstr. 5 //
48 // 37077 Goettingen //
49 // Germany //
50 // //
51 // e-mail: oconrad@saga-gis.org //
52 // //
54 
55 //---------------------------------------------------------
56 
57 
59 // //
60 // //
61 // //
63 
64 //---------------------------------------------------------
65 #include "api_core.h"
66 
67 #include "table.h"
68 
69 
71 // //
72 // //
73 // //
75 
76 //---------------------------------------------------------
78 
79 //---------------------------------------------------------
81 {
82  return( gSG_Translator );
83 }
84 
85 
87 // //
88 // //
89 // //
91 
92 //---------------------------------------------------------
93 const SG_Char * SG_Translate(const CSG_String &Text)
94 {
95  return( gSG_Translator.Get_Translation(Text) );
96 }
97 
98 
100 // //
101 // //
102 // //
104 
105 //---------------------------------------------------------
107 {
108  m_nTranslations = 0;
109  m_Translations = NULL;
110 }
111 
112 CSG_Translator::CSG_Translator(const CSG_String &File_Name, bool bSetExtension, int iText, int iTranslation, bool bCmpNoCase)
113 {
114  m_nTranslations = 0;
115  m_Translations = NULL;
116 
117  Create(File_Name, bSetExtension, iText, iTranslation, bCmpNoCase);
118 }
119 
120 CSG_Translator::CSG_Translator(class CSG_Table *pTable, int iText, int iTranslation, bool bCmpNoCase)
121 {
122  m_nTranslations = 0;
123  m_Translations = NULL;
124 
125  Create(pTable, iText, iTranslation, bCmpNoCase);
126 }
127 
128 //---------------------------------------------------------
130 {
131  Destroy();
132 }
133 
134 //---------------------------------------------------------
136 {
137  if( m_Translations )
138  {
139  for(int i=0; i<m_nTranslations; i++)
140  {
141  delete(m_Translations[i]);
142  }
143 
144  SG_Free(m_Translations);
145 
146  m_nTranslations = 0;
147  m_Translations = NULL;
148  }
149 }
150 
151 
153 // //
155 
156 //---------------------------------------------------------
157 bool CSG_Translator::Create(const CSG_String &File_Name, bool bSetExtension, int iText, int iTranslation, bool bCmpNoCase)
158 {
159  CSG_Table Translations;
160  CSG_String fName(bSetExtension ? SG_File_Make_Path("", File_Name, "lng") : File_Name);
161 
162  SG_UI_Msg_Lock(true);
163 
164  Destroy();
165 
166  if( SG_File_Exists(fName) && Translations.Create(fName, TABLE_FILETYPE_Text, SG_FILE_ENCODING_UTF8) )
167  {
168  Create(&Translations, iText, iTranslation, bCmpNoCase);
169  }
170 
171  SG_UI_Msg_Lock(false);
172 
173  return( m_nTranslations > 0 );
174 }
175 
176 //---------------------------------------------------------
177 bool CSG_Translator::Create(class CSG_Table *pTranslations, int iText, int iTranslation, bool bCmpNoCase)
178 {
179  SG_UI_Msg_Lock(true);
180 
181  Destroy();
182 
183  if( iText != iTranslation && pTranslations && pTranslations->Get_Field_Count() > iText && pTranslations->Get_Field_Count() > iTranslation && pTranslations->Get_Count() > 0 )
184  {
185  int i;
186 
187  m_bCmpNoCase = bCmpNoCase;
188 
189  if( m_bCmpNoCase )
190  {
191  for(i=0; i<pTranslations->Get_Count(); i++)
192  {
193  CSG_Table_Record *pRecord = pTranslations->Get_Record(i);
194 
195  if( !pRecord->is_NoData(iText) )
196  {
197  CSG_String s = pRecord->asString(iText);
198 
199  pRecord->Set_Value(iText, s.Make_Lower().c_str());
200  }
201  }
202  }
203 
204  pTranslations->Set_Index(iText, TABLE_INDEX_Ascending);
205 
206  m_Translations = (CSG_Translation **)SG_Malloc(pTranslations->Get_Count() * sizeof(CSG_Translation *));
207 
208  for(i=0; i<pTranslations->Get_Count(); i++)
209  {
210  CSG_Table_Record *pRecord = pTranslations->Get_Record_byIndex(i);
211 
212  if( !pRecord->is_NoData(iText) && !pRecord->is_NoData(iTranslation) )
213  {
214  m_Translations[m_nTranslations++] = new CSG_Translation(pRecord->asString(iText), pRecord->asString(iTranslation));
215  }
216  }
217 
218  if( m_nTranslations < pTranslations->Get_Count() )
219  {
220  m_Translations = (CSG_Translation **)SG_Realloc(m_Translations, m_nTranslations * sizeof(CSG_Translation *));
221  }
222  }
223 
224  SG_UI_Msg_Lock(false);
225 
226  return( m_nTranslations > 0 );
227 }
228 
229 
231 // //
233 
234 //---------------------------------------------------------
235 #define COMPARE(Index, Text) (m_bCmpNoCase ? m_Translations[Index]->m_Text.CmpNoCase(Text) : m_Translations[Index]->m_Text.Cmp(Text))
236 
237 //---------------------------------------------------------
238 int CSG_Translator::_Get_Index(const CSG_String &Text) const
239 {
240  int a, b, i, c;
241 
242  if( m_nTranslations == 1 )
243  {
244  c = COMPARE(0, Text);
245 
246  return( c >= 0 ? 0 : 1 );
247  }
248 
249  if( m_nTranslations > 1 )
250  {
251  for(a=0, b=m_nTranslations-1; b - a > 1; )
252  {
253  i = a + (b - a) / 2;
254  c = COMPARE(i, Text);
255 
256  if( c > 0 )
257  {
258  b = i;
259  }
260  else if( c < 0 )
261  {
262  a = i;
263  }
264  else
265  {
266  return( i );
267  }
268  }
269 
270  if( COMPARE(a, Text) < 0 )
271  {
272  if( COMPARE(b, Text) < 0 )
273  {
274  return( m_nTranslations );
275  }
276 
277  return( b );
278  }
279 
280  if( COMPARE(b, Text) > 0 )
281  {
282  return( a );
283  }
284  }
285 
286  return( m_nTranslations );
287 }
288 
289 
291 // //
293 
294 //---------------------------------------------------------
295 const SG_Char * CSG_Translator::Get_Translation(const SG_Char *Text, bool bReturnNullOnNotFound) const
296 {
297  if( Text )
298  {
299  if( m_nTranslations > 0 )
300  {
301  int i;
302  CSG_String s(Text);
303 
304  if( *Text == '{' )
305  {
306  s = s.AfterFirst('{').BeforeFirst('}');
307  }
308 
309  if( (i = _Get_Index(s)) < m_nTranslations && !COMPARE(i, s) )
310  {
311  return( m_Translations[i]->m_Translation );
312  }
313  }
314 
315  if( bReturnNullOnNotFound )
316  {
317  return( NULL );
318  }
319 
320  //-------------------------------------------------
321  if( *Text == '{' )
322  {
323  do { Text++; } while( *Text != '}' && *Text != '\0' );
324  do { Text++; } while( *Text == ' ' && *Text != '\0' );
325  }
326  }
327 
328  return( Text );
329 }
330 
331 //---------------------------------------------------------
332 bool CSG_Translator::Get_Translation(const SG_Char *Text, CSG_String &Translation) const
333 {
334  if( Text )
335  {
336  if( m_nTranslations > 0 )
337  {
338  int i;
339  CSG_String s(Text);
340 
341  if( *Text == '{' )
342  {
343  s = s.AfterFirst('{').BeforeFirst('}');
344  }
345 
346  if( (i = _Get_Index(s)) < m_nTranslations && !COMPARE(i, s) )
347  {
348  Translation = m_Translations[i]->m_Translation;
349 
350  return( true );
351  }
352  }
353 
354  //-------------------------------------------------
355  if( *Text == '{' )
356  {
357  do { Text++; } while( *Text != '}' && *Text != '\0' );
358  do { Text++; } while( *Text == ' ' && *Text != '\0' );
359  }
360 
361  Translation = Text;
362  }
363 
364  return( false );
365 }
366 
367 
369 // //
370 // //
371 // //
373 
374 //---------------------------------------------------------
CSG_String::BeforeFirst
CSG_String BeforeFirst(char Character) const
Definition: api_string.cpp:666
CSG_Translator
Definition: api_core.h:1433
CSG_String::Make_Lower
CSG_String & Make_Lower(void)
Definition: api_string.cpp:543
CSG_Translator::CSG_Translator
CSG_Translator(void)
Definition: api_translator.cpp:106
CSG_Table_Record
Definition: table.h:130
COMPARE
#define COMPARE(Index, Text)
Definition: api_translator.cpp:235
CSG_Table::Get_Record
virtual CSG_Table_Record * Get_Record(sLong Index) const
Definition: table.h:394
SG_Malloc
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
Definition: api_memory.cpp:65
CSG_Translator::Destroy
void Destroy(void)
Definition: api_translator.cpp:135
api_core.h
CSG_Table::Get_Field_Count
int Get_Field_Count(void) const
Definition: table.h:356
SG_Free
SAGA_API_DLL_EXPORT void SG_Free(void *memblock)
Definition: api_memory.cpp:83
gSG_Translator
CSG_Translator gSG_Translator
Definition: api_translator.cpp:77
CSG_Table_Record::is_NoData
bool is_NoData(int Field) const
Definition: table_record.cpp:416
SG_File_Exists
SAGA_API_DLL_EXPORT bool SG_File_Exists(const CSG_String &FileName)
Definition: api_file.cpp:850
CSG_Table_Record::asString
const SG_Char * asString(int Field, int Decimals=-99) const
Definition: table_record.cpp:461
CSG_Translator::~CSG_Translator
virtual ~CSG_Translator(void)
Definition: api_translator.cpp:129
SG_Get_Translator
CSG_Translator & SG_Get_Translator(void)
Definition: api_translator.cpp:80
SG_UI_Msg_Lock
int SG_UI_Msg_Lock(bool bOn)
Definition: api_callback.cpp:472
CSG_Table::Get_Count
sLong Get_Count(void) const
Definition: table.h:392
CSG_Translator::Get_Translation
const SG_Char * Get_Translation(int i) const
Definition: api_core.h:1450
CSG_Table::Get_Record_byIndex
CSG_Table_Record * Get_Record_byIndex(sLong Index) const
Definition: table.h:399
CSG_Table
Definition: table.h:283
CSG_Translator::Create
bool Create(const CSG_String &File_Name, bool bSetExtension=true, int iText=0, int iTranslation=1, bool bCmpNoCase=false)
Definition: api_translator.cpp:157
SG_Translate
const SG_Char * SG_Translate(const CSG_String &Text)
Definition: api_translator.cpp:93
CSG_String::AfterFirst
CSG_String AfterFirst(char Character) const
Definition: api_string.cpp:644
CSG_Translator::Get_Count
int Get_Count(void) const
Definition: api_core.h:1448
SG_Char
#define SG_Char
Definition: api_core.h:536
CSG_String
Definition: api_core.h:563
CSG_Table_Record::Set_Value
bool Set_Value(int Field, const CSG_String &Value)
Definition: table_record.cpp:270
TABLE_INDEX_Ascending
@ TABLE_INDEX_Ascending
Definition: table.h:105
CSG_Table::Create
bool Create(void)
Definition: table.cpp:139
SG_File_Make_Path
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
Definition: api_file.cpp:919
CSG_String::c_str
const SG_Char * c_str(void) const
Definition: api_string.cpp:236
TABLE_FILETYPE_Text
@ TABLE_FILETYPE_Text
Definition: table.h:95
SG_Realloc
SAGA_API_DLL_EXPORT void * SG_Realloc(void *memblock, size_t size)
Definition: api_memory.cpp:77
CSG_Table::Set_Index
bool Set_Index(CSG_Index &Index, int Field, bool bAscending=true) const
Definition: table.cpp:1426
SG_FILE_ENCODING_UTF8
@ SG_FILE_ENCODING_UTF8
Definition: api_core.h:552
table.h