OpenClonk
C4Language Class Reference

#include <C4Language.h>

Public Member Functions

 C4Language ()
 
 ~C4Language ()
 
bool CloseGroup (const char *strPath)
 
void ClearLanguage ()
 
bool Init ()
 
void Clear ()
 
int GetPackCount ()
 
C4GroupSet GetPackGroups (C4Group &)
 
int GetInfoCount ()
 
C4LanguageInfoGetInfo (int iIndex)
 
C4LanguageInfoFindInfo (const char *strCode)
 
bool LoadLanguage (const char *strLanguages)
 
bool HasStringTable () const
 

Static Public Member Functions

static bool LoadComponentHost (C4ComponentHost *host, C4Group &hGroup, const char *szFilename, const char *szLanguage)
 

Detailed Description

Definition at line 40 of file C4Language.h.

Constructor & Destructor Documentation

◆ C4Language()

C4Language::C4Language ( )

Definition at line 44 of file C4Language.cpp.

45 {
46  Infos = nullptr;
47  PackGroupLocation[0] = 0;
48 }

◆ ~C4Language()

C4Language::~C4Language ( )

Definition at line 50 of file C4Language.cpp.

51 {
52  Clear();
53 }
void Clear()
Definition: C4Language.cpp:114

References Clear().

Here is the call graph for this function:

Member Function Documentation

◆ Clear()

void C4Language::Clear ( )

Definition at line 114 of file C4Language.cpp.

115 {
116  // Clear pack groups
117  PackGroups.Clear();
118  // Clear packs
119  Packs.Clear();
120  // Close pack directory
121  PackDirectory.Close();
122  // Clear infos
123  C4LanguageInfo* pNext;
124  while (Infos)
125  {
126  pNext = Infos->Next;
127  delete Infos;
128  Infos = pNext;
129  }
130  Infos = nullptr;
131 }
bool Close()
Definition: C4Group.cpp:971
void Clear()
Definition: C4GroupSet.cpp:50

References C4GroupSet::Clear(), and C4Group::Close().

Referenced by C4Application::Clear(), Init(), and ~C4Language().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearLanguage()

void C4Language::ClearLanguage ( )

Definition at line 410 of file C4Language.cpp.

411 {
412  // Clear resource string table
414 }
static C4LangStringTable & GetSystemStringTable()

References C4ComponentHost::Clear(), and C4LangStringTable::GetSystemStringTable().

Referenced by C4Application::Clear(), and LoadLanguage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CloseGroup()

bool C4Language::CloseGroup ( const char *  strPath)

Definition at line 418 of file C4Language.cpp.

419 {
420  // Check all open language packs
421  C4Group *pPack;
422  for (int iPack = 0; (pPack = Packs.GetGroup(iPack)); iPack++)
423  if (ItemIdentical(strPath, pPack->GetFullName().getData()))
424  {
425  Packs.UnregisterGroup(iPack);
426  return true;
427  }
428  // No pack of that path
429  return false;
430 }
bool ItemIdentical(const char *szFilename1, const char *szFilename2)
Definition: StdFile.cpp:879
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
bool UnregisterGroup(int32_t iIndex)
Definition: C4GroupSet.cpp:274
C4Group * GetGroup(int32_t iIndex)
Definition: C4GroupSet.cpp:259
const char * getData() const
Definition: StdBuf.h:442

References StdStrBuf::getData(), C4Group::GetFullName(), C4GroupSet::GetGroup(), ItemIdentical(), and C4GroupSet::UnregisterGroup().

Here is the call graph for this function:

◆ FindInfo()

C4LanguageInfo * C4Language::FindInfo ( const char *  strCode)

Definition at line 353 of file C4Language.cpp.

354 {
355  for (C4LanguageInfo *pInfo = Infos; pInfo; pInfo = pInfo->Next)
356  if (SEqualNoCase(pInfo->Code, strCode, 2))
357  return pInfo;
358  return nullptr;
359 }
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:213

References C4LanguageInfo::Code, and SEqualNoCase().

Here is the call graph for this function:

◆ GetInfo()

C4LanguageInfo * C4Language::GetInfo ( int  iIndex)

Definition at line 343 of file C4Language.cpp.

344 {
345  for (C4LanguageInfo *pInfo = Infos; pInfo; pInfo = pInfo->Next)
346  if (iIndex <= 0)
347  return pInfo;
348  else
349  iIndex--;
350  return nullptr;
351 }

◆ GetInfoCount()

int C4Language::GetInfoCount ( )

Definition at line 138 of file C4Language.cpp.

139 {
140  int iCount = 0;
141  for (C4LanguageInfo *pInfo = Infos; pInfo; pInfo = pInfo->Next)
142  iCount++;
143  return iCount;
144 }

◆ GetPackCount()

int C4Language::GetPackCount ( )

Definition at line 133 of file C4Language.cpp.

134 {
135  return Packs.GetGroupCount();
136 }
int32_t GetGroupCount()
Definition: C4GroupSet.cpp:251

References C4GroupSet::GetGroupCount().

Here is the call graph for this function:

◆ GetPackGroups()

C4GroupSet C4Language::GetPackGroups ( C4Group hGroup)

Definition at line 148 of file C4Language.cpp.

149 {
150  // Build a group set containing the provided group and
151  // alternative groups for cross-loading from a language pack
152  char strRelativePath[_MAX_PATH_LEN];
153  char strTargetLocation[_MAX_PATH_LEN];
154  char strPackPath[_MAX_PATH_LEN];
155  char strPackGroupLocation[_MAX_PATH_LEN];
156  char strAdvance[_MAX_PATH_LEN];
157 
158  // Store wanted target location
159  SCopy(Config.AtRelativePath(hGroup.GetFullName().getData()), strRelativePath, _MAX_PATH);
160  SCopy(strRelativePath, strTargetLocation, _MAX_PATH);
161 
162  // Adjust location by scenario origin
164  {
165  const char *szScenarioRelativePath = GetRelativePathS(strRelativePath, Config.AtRelativePath(Game.ScenarioFilename));
166  if (szScenarioRelativePath != strRelativePath)
167  {
168  // this is a path within the scenario! Change to origin.
169  size_t iRestPathLen = SLen(szScenarioRelativePath);
170  if (Game.C4S.Head.Origin.getLength() + 1 + iRestPathLen <= _MAX_PATH)
171  {
172  SCopy(Game.C4S.Head.Origin.getData(), strTargetLocation);
173  if (iRestPathLen)
174  {
175  SAppendChar(DirectorySeparator, strTargetLocation);
176  SAppend(szScenarioRelativePath, strTargetLocation);
177  }
178  }
179  }
180  }
181 
182  // Process all language packs (and their respective pack groups)
183  C4Group *pPack, *pPackGroup;
184  for (int iPack = 0; (pPack = Packs.GetGroup(iPack)) && (pPackGroup = PackGroups.GetGroup(iPack)); iPack++)
185  {
186  // Get current pack group position within pack
187  SCopy(pPack->GetFullName().getData(), strPackPath, _MAX_PATH);
188  GetRelativePath(pPackGroup->GetFullName().getData(), strPackPath, strPackGroupLocation);
189 
190  // Pack group is at correct position within pack: continue with next pack
191  if (SEqualNoCase(strPackGroupLocation, strTargetLocation))
192  continue;
193 
194  // Try to backtrack until we can reach the target location as a relative child
195  while ( strPackGroupLocation[0]
196  && !GetRelativePath(strTargetLocation, strPackGroupLocation, strAdvance)
197  && pPackGroup->OpenMother() )
198  {
199  // Update pack group location
200  GetRelativePath(pPackGroup->GetFullName().getData(), strPackPath, strPackGroupLocation);
201  }
202 
203  // We can reach the target location as a relative child
204  if (strPackGroupLocation[0] && GetRelativePath(strTargetLocation, strPackGroupLocation, strAdvance))
205  {
206  // Advance pack group to relative child
207  pPackGroup->OpenChild(strAdvance);
208  }
209 
210  // Cannot reach by advancing: need to close and reopen (rewinding group file)
211  else
212  {
213  // Close pack group (if it is open at all)
214  pPackGroup->Close();
215  // Reopen pack group to relative position in language pack if possible
216  pPackGroup->OpenAsChild(pPack, strTargetLocation);
217  }
218 
219  }
220 
221  // Store new target location
222  SCopy(strTargetLocation, PackGroupLocation, _MAX_FNAME);
223 
224  C4GroupSet r;
225  // Provided group gets highest priority
226  r.RegisterGroup(hGroup, false, 1000, C4GSCnt_Component);
227  // register currently open pack groups
228  r.RegisterGroups(PackGroups, C4GSCnt_Language);
229  return r;
230 }
C4Config Config
Definition: C4Config.cpp:930
C4Game Game
Definition: C4Globals.cpp:52
#define C4GSCnt_Component
Definition: C4GroupSet.h:41
#define C4GSCnt_Language
Definition: C4GroupSet.h:40
#define _MAX_FNAME
#define DirectorySeparator
#define _MAX_PATH
#define _MAX_PATH_LEN
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
void SAppendChar(char cChar, char *szStr)
Definition: Standard.cpp:271
void SAppend(const char *szSource, char *szTarget, int iMaxL)
Definition: Standard.cpp:263
size_t SLen(const char *sptr)
Definition: Standard.h:74
const char * GetRelativePathS(const char *strPath, const char *strRelativeTo)
Definition: StdFile.cpp:208
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:118
const char * AtRelativePath(const char *filename)
Definition: C4Config.cpp:741
C4Scenario C4S
Definition: C4Game.h:74
char ScenarioFilename[_MAX_PATH_LEN]
Definition: C4Game.h:102
bool OpenAsChild(C4Group *mother, const char *entry_name, bool is_exclusive=false, bool do_create=false)
Definition: C4Group.cpp:1952
bool OpenChild(const char *entry_name)
Definition: C4Group.cpp:2765
bool OpenMother()
Definition: C4Group.cpp:2803
bool RegisterGroup(C4Group &rGroup, bool fOwnGrp, int32_t Priority, int32_t Contents, bool fCheckContent=true)
Definition: C4GroupSet.cpp:88
bool RegisterGroups(const C4GroupSet &rCopy, int32_t Contents, const char *szFilename=nullptr, int32_t iMaxSkipID=0)
Definition: C4GroupSet.cpp:128
StdCopyStrBuf Origin
Definition: C4Scenario.h:80
C4SHead Head
Definition: C4Scenario.h:232
size_t getLength() const
Definition: StdBuf.h:445

References _MAX_PATH, _MAX_PATH_LEN, C4Config::AtRelativePath(), C4Game::C4S, Config, DirectorySeparator, Game, StdStrBuf::getData(), GetExtension(), C4Group::GetFullName(), C4GroupSet::GetGroup(), StdStrBuf::getLength(), GetRelativePathS(), C4Scenario::Head, C4SHead::Origin, SAppend(), SAppendChar(), C4Game::ScenarioFilename, SCopy(), SEqualNoCase(), and SLen().

Referenced by LoadComponentHost().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HasStringTable()

bool C4Language::HasStringTable ( ) const
inline

Definition at line 70 of file C4Language.h.

const StdStrBuf & GetDataBuf() const
bool isNull() const
Definition: StdBuf.h:441

References C4ComponentHost::GetDataBuf(), C4LangStringTable::GetSystemStringTable(), and StdStrBuf::isNull().

Referenced by C4Game::Clear(), C4Application::Clear(), and C4Application::DoInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Init()

bool C4Language::Init ( )

Definition at line 55 of file C4Language.cpp.

56 {
57  // Clear (to allow clean re-init)
58  Clear();
59 
60  // Make sure Language.ocg is unpacked (TODO: This won't work properly if Language.ocg is in system data path)
61  // Assume for now that Language.ocg is either at a writable location or unpacked already.
62  // TODO: Use all Language.c4gs that we find, and merge them.
63  // TODO: Use gettext instead?
64  StdStrBuf langPath;
65  C4Reloc::iterator iter;
66  for(iter = Reloc.begin(); iter != Reloc.end(); ++iter)
67  {
68  langPath.Copy(iter->strBuf + DirSep + C4CFN_Languages);
69  if(ItemExists(langPath.getData()))
70  {
71  if(DirectoryExists(langPath.getData()))
72  break;
73  if(C4Group_UnpackDirectory(langPath.getData()))
74  break;
75  }
76  }
77 
78  // Break if no language.ocg found
79  if(iter != Reloc.end())
80  {
81  // Look for available language packs in Language.ocg
82  C4Group *pPack;
83  char strPackFilename[_MAX_FNAME_LEN], strEntry[_MAX_FNAME_LEN];
84  if (PackDirectory.Open(langPath.getData()))
85  {
86  while (PackDirectory.FindNextEntry("*.ocg", strEntry))
87  {
88  sprintf(strPackFilename, "%s" DirSep "%s", C4CFN_Languages, strEntry);
89  pPack = new C4Group();
90  if (pPack->Open(strPackFilename))
91  {
92  Packs.RegisterGroup(*pPack, true, C4GSCnt_Language, false);
93  }
94  else
95  {
96  delete pPack;
97  }
98  }
99  }
100 
101  // Now create a pack group for each language pack (these pack groups are child groups
102  // that browse along each pack to access requested data)
103  for (int iPack = 0; (pPack = Packs.GetGroup(iPack)); iPack++)
104  PackGroups.RegisterGroup(*(new C4Group), true, C4GSPrio_Base, C4GSCnt_Language);
105  }
106 
107  // Load language infos by scanning string tables (the engine doesn't really need this at the moment)
108  InitInfos();
109 
110  // Done
111  return true;
112 }
#define C4CFN_Languages
Definition: C4Components.h:32
bool C4Group_UnpackDirectory(const char *filename)
Definition: C4Group.cpp:401
#define C4GSPrio_Base
Definition: C4GroupSet.h:23
C4Reloc Reloc
Definition: C4Reloc.cpp:21
#define DirSep
#define _MAX_FNAME_LEN
#define sprintf
Definition: Standard.h:162
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:708
bool ItemExists(const char *szItemName)
Definition: StdFile.h:75
bool FindNextEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr, bool start_at_filename=false)
Definition: C4Group.cpp:2217
bool Open(const char *group_name, bool do_create=false)
Definition: C4Group.cpp:660
iterator end() const
Definition: C4Reloc.cpp:149
iterator begin() const
Definition: C4Reloc.cpp:142
void Copy()
Definition: StdBuf.h:467
StdCopyStrBuf strBuf
Definition: C4Reloc.h:33

References _MAX_FNAME_LEN, C4Reloc::begin(), C4CFN_Languages, C4Group_UnpackDirectory(), C4GSCnt_Language, C4GSPrio_Base, Clear(), StdStrBuf::Copy(), DirectoryExists(), DirSep, C4Reloc::end(), C4Group::FindNextEntry(), StdStrBuf::getData(), C4GroupSet::GetGroup(), ItemExists(), C4Group::Open(), C4GroupSet::RegisterGroup(), Reloc, sprintf, and C4Reloc::PathInfo::strBuf.

Referenced by C4Application::DoInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadComponentHost()

bool C4Language::LoadComponentHost ( C4ComponentHost host,
C4Group hGroup,
const char *  szFilename,
const char *  szLanguage 
)
static

Definition at line 232 of file C4Language.cpp.

233 {
234  assert(host);
235  if (!host) return false;
236  C4GroupSet hGroups = ::Languages.GetPackGroups(hGroup);
237  return host->Load(hGroups, szFilename, szLanguage);
238 }
C4Language Languages
Definition: C4Language.cpp:42
bool Load(C4Group &hGroup, const char *szFilename, const char *szLanguage=nullptr)
C4GroupSet GetPackGroups(C4Group &)
Definition: C4Language.cpp:148

References GetPackGroups(), Languages, and C4ComponentHost::Load().

Referenced by C4ScenarioListLoader::SubFolder::DoLoadContents(), C4MapFolderData::Load(), C4RankSystem::Load(), C4DefList::Load(), C4ScenarioListLoader::Entry::Load(), C4Game::LoadAdditionalSystemGroup(), C4ScenarioListLoader::Scenario::LoadCustomPre(), C4Game::OpenScenario(), and C4Game::UpdateLanguage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadLanguage()

bool C4Language::LoadLanguage ( const char *  strLanguages)

Definition at line 361 of file C4Language.cpp.

362 {
363  // Clear old string table
364  ClearLanguage();
365  // Try to load string table according to language sequence
366  char strLanguageCode[2 + 1];
367  for (int i = 0; SCopySegment(strLanguages, i, strLanguageCode, ',', 2, true); i++)
368  if (InitStringTable(strLanguageCode))
369  return true;
370  // No matching string table found: hardcoded fallback to US
371  if (InitStringTable("US"))
372  return true;
373  // No string table present: this is really bad
374  Log("Error loading language string table.");
375  return false;
376 }
bool Log(const char *szMessage)
Definition: C4Log.cpp:204
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
Definition: Standard.cpp:279
void ClearLanguage()
Definition: C4Language.cpp:410

References ClearLanguage(), Log(), and SCopySegment().

Referenced by C4Application::DoInit().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: