OpenClonk
C4LangStringTable Class Reference

#include <C4LangStringTable.h>

Inheritance diagram for C4LangStringTable:
[legend]
Collaboration diagram for C4LangStringTable:
[legend]

Classes

class  NoSuchTranslation
 

Public Member Functions

 C4LangStringTable ()=default
 
const std::string & Translate (const std::string &text) const
 
bool HasTranslation (const std::string &text) const
 
void ReplaceStrings (StdStrBuf &rBuf)
 
void ReplaceStrings (const StdStrBuf &rBuf, StdStrBuf &rTarget)
 
void AddRef ()
 
void DelRef ()
 
const char * GetFilePath () const
 
void Clear ()
 
const char * GetData () const
 
const StdStrBufGetDataBuf () const
 
size_t GetDataSize () const
 
bool Load (C4Group &hGroup, const char *szFilename, const char *szLanguage=nullptr)
 
bool Load (C4GroupSet &hGroupSet, const char *szFilename, const char *szLanguage=nullptr)
 
bool GetLanguageString (const char *szLanguage, StdStrBuf &rTarget)
 

Static Public Member Functions

static C4LangStringTableGetSystemStringTable ()
 

Protected Member Functions

void OnLoad () override
 
void CopyFilePathFromGroup (const C4Group &hGroup)
 
void FinishLoad (const StdStrBuf &, C4Group &hGroup)
 

Protected Attributes

StdCopyStrBuf Data
 
StdCopyStrBuf Filename
 
StdCopyStrBuf FilePath
 

Detailed Description

Definition at line 23 of file C4LangStringTable.h.

Constructor & Destructor Documentation

◆ C4LangStringTable()

C4LangStringTable::C4LangStringTable ( )
default

Member Function Documentation

◆ AddRef()

void C4LangStringTable::AddRef ( )
inline

Definition at line 39 of file C4LangStringTable.h.

39 { ++ref_count; }

Referenced by C4ScriptHost::Load(), and C4ScriptHost::LoadData().

Here is the caller graph for this function:

◆ Clear()

void C4ComponentHost::Clear ( )
inlineinherited

Definition at line 29 of file C4ComponentHost.h.

29 { Data.Clear(); OnLoad(); }
virtual void OnLoad()
StdCopyStrBuf Data
void Clear()
Definition: StdBuf.h:466

References StdStrBuf::Clear(), C4ComponentHost::Data, and C4ComponentHost::OnLoad().

Referenced by C4Game::Clear(), C4Def::Clear(), C4ScriptHost::Clear(), C4Language::ClearLanguage(), C4Def::Default(), C4ComponentHost::Load(), and C4ComponentHost::~C4ComponentHost().

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

◆ CopyFilePathFromGroup()

void C4ComponentHost::CopyFilePathFromGroup ( const C4Group hGroup)
protectedinherited

Definition at line 120 of file C4ComponentHost.cpp.

121 {
125 }
C4Config Config
Definition: C4Config.cpp:930
StdCopyStrBuf Filename
StdCopyStrBuf FilePath
const char * AtRelativePath(const char *filename)
Definition: C4Config.cpp:741
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
const char * getData() const
Definition: StdBuf.h:442
void AppendBackslash()
Definition: StdBuf.cpp:248
void Copy()
Definition: StdBuf.h:467
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519

References StdStrBuf::Append(), StdStrBuf::AppendBackslash(), C4Config::AtRelativePath(), Config, StdStrBuf::Copy(), C4ComponentHost::Filename, C4ComponentHost::FilePath, StdStrBuf::getData(), and C4Group::GetFullName().

Referenced by C4ComponentHost::FinishLoad(), and C4ComponentHost::Load().

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

◆ DelRef()

void C4LangStringTable::DelRef ( )
inline

Definition at line 40 of file C4LangStringTable.h.

40 { if (!--ref_count) delete this; }

Referenced by C4ScriptHost::Clear(), C4ScriptHost::Load(), C4Game::LoadAdditionalSystemGroup(), and C4ScriptHost::LoadData().

Here is the caller graph for this function:

◆ FinishLoad()

void C4ComponentHost::FinishLoad ( const StdStrBuf name,
C4Group hGroup 
)
protectedinherited

Definition at line 99 of file C4ComponentHost.cpp.

100 {
101  // Store actual filename
102  hGroup.FindEntry(name.getData(), &Filename);
103  CopyFilePathFromGroup(hGroup);
104 
105  if (Data.EnsureUnicode())
106  {
107  LogF("WARNING: File is not encoded as UTF-8 (%s)", FilePath.getData());
108  }
109  // Skip those stupid "zero width no-break spaces" (also known as Byte Order Marks)
110  if (Data[0] == '\xEF' && Data[1] == '\xBB' && Data[2] == '\xBF')
111  {
112  Data.Move(3,Data.getSize()-3);
113  Data.Shrink(3);
114  }
115  // Notify
116  OnLoad();
117 }
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
void CopyFilePathFromGroup(const C4Group &hGroup)
bool FindEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr)
Definition: C4Group.cpp:2211
size_t getSize() const
Definition: StdBuf.h:444
void Move(size_t iFrom, size_t inSize, size_t iTo=0)
Definition: StdBuf.h:471
void Shrink(size_t iShrink)
Definition: StdBuf.h:503
bool EnsureUnicode()
Definition: StdBuf.cpp:421

References C4ComponentHost::CopyFilePathFromGroup(), C4ComponentHost::Data, StdStrBuf::EnsureUnicode(), C4ComponentHost::Filename, C4ComponentHost::FilePath, C4Group::FindEntry(), StdStrBuf::getData(), StdStrBuf::getSize(), LogF(), StdStrBuf::Move(), C4ComponentHost::OnLoad(), and StdStrBuf::Shrink().

Referenced by C4ComponentHost::Load().

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

◆ GetData()

const char* C4ComponentHost::GetData ( ) const
inlineinherited

Definition at line 30 of file C4ComponentHost.h.

30 { return Data.getData(); }

References C4ComponentHost::Data, and StdStrBuf::getData().

Referenced by C4Game::CompileRuntimeData(), C4RankSystem::Load(), C4ScenarioListLoader::Entry::Load(), C4Player::LoadRuntimeData(), C4ObjectInfoList::New(), and C4Game::OpenScenario().

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

◆ GetDataBuf()

const StdStrBuf& C4ComponentHost::GetDataBuf ( ) const
inlineinherited

Definition at line 31 of file C4ComponentHost.h.

31 { return Data; }

References C4ComponentHost::Data.

Referenced by C4Game::CompileRuntimeData(), C4Language::HasStringTable(), and C4ScriptHost::MakeScript().

Here is the caller graph for this function:

◆ GetDataSize()

size_t C4ComponentHost::GetDataSize ( ) const
inlineinherited

Definition at line 32 of file C4ComponentHost.h.

32 { return Data.getLength(); }
size_t getLength() const
Definition: StdBuf.h:445

References C4ComponentHost::Data, and StdStrBuf::getLength().

Referenced by C4RankSystem::Load().

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

◆ GetFilePath()

const char* C4ComponentHost::GetFilePath ( ) const
inlineinherited

Definition at line 28 of file C4ComponentHost.h.

28 { return FilePath.getData(); }

References C4ComponentHost::FilePath, and StdStrBuf::getData().

Referenced by C4ScriptHost::Load(), C4Player::LoadRuntimeData(), C4ScriptHost::ReloadScript(), and ReplaceStrings().

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

◆ GetLanguageString()

bool C4ComponentHost::GetLanguageString ( const char *  szLanguage,
StdStrBuf rTarget 
)
inherited

Definition at line 127 of file C4ComponentHost.cpp.

128 {
129  const char *cptr;
130  // No good parameters
131  if (!szLanguage || !Data) return false;
132  // Search for two-letter language identifier in text body, i.e. "DE:"
133  char langindex[4] = "";
134  for (int clseg=0; SCopySegment(szLanguage ? szLanguage : "", clseg, langindex, ',', 2); clseg++)
135  {
136  SAppend(":",langindex);
137  if ((cptr = SSearch(Data.getData(),langindex)))
138  {
139  // Return the according string
140  int iEndPos = SCharPos('\r', cptr);
141  if (iEndPos<0) iEndPos = SCharPos('\n', cptr);
142  if (iEndPos<0) iEndPos = strlen(cptr);
143  rTarget.Copy(cptr, iEndPos);
144  return true;
145  }
146  }
147  // Language string not found
148  return false;
149 }
const char * SSearch(const char *szString, const char *szIndex)
Definition: Standard.cpp:369
int SCharPos(char cTarget, const char *szInStr, int iIndex)
Definition: Standard.cpp:239
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
Definition: Standard.cpp:279
void SAppend(const char *szSource, char *szTarget, int iMaxL)
Definition: Standard.cpp:263

References StdStrBuf::Copy(), C4ComponentHost::Data, StdStrBuf::getData(), SAppend(), SCharPos(), SCopySegment(), and SSearch().

Referenced by C4DefList::Load(), C4ScenarioListLoader::Entry::Load(), and C4Game::OpenScenario().

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

◆ GetSystemStringTable()

static C4LangStringTable& C4LangStringTable::GetSystemStringTable ( )
inlinestatic

Definition at line 48 of file C4LangStringTable.h.

48 { return system_string_table; }

Referenced by C4Language::ClearLanguage(), C4Language::HasStringTable(), and LoadResStr().

Here is the caller graph for this function:

◆ HasTranslation()

bool C4LangStringTable::HasTranslation ( const std::string &  text) const

Definition at line 23 of file C4LangStringTable.cpp.

24 {
25  if (strings.empty())
26  PopulateStringTable();
27  return strings.find(text) != strings.end();
28 }

References C4ScriptGuiWindowPropertyName::text.

◆ Load() [1/2]

bool C4ComponentHost::Load ( C4Group hGroup,
const char *  szFilename,
const char *  szLanguage = nullptr 
)
inherited

Definition at line 23 of file C4ComponentHost.cpp.

26 {
27  // Clear any old stuff
28  Clear();
29  // Store filename
30  if (fname)
31  Filename.Copy(fname);
32  // Load component - try all segmented filenames
33  char strEntry[_MAX_FNAME_LEN];
34  StdStrBuf strEntryWithLanguage;
35  for (int iFilename = 0; SCopySegment(Filename.getData(), iFilename, strEntry, '|'); iFilename++)
36  {
37  // Try to insert all language codes provided into the filename
38  char strCode[3] = "";
39  for (int iLang = 0; SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2); iLang++)
40  {
41  // Insert language code
42  strEntryWithLanguage.Format(strEntry, strCode);
43  if (hGroup.LoadEntryString(strEntryWithLanguage, &Data))
44  {
45  FinishLoad(strEntryWithLanguage, hGroup);
46  // Got it
47  return true;
48  }
49  // Couldn't insert language code anyway - no point in trying other languages
50  if (!SSearch(strEntry, "%s")) break;
51  }
52  }
53  // Truncate any additional segments from stored filename
54  SReplaceChar(Filename.getMData(), '|', 0);
55  CopyFilePathFromGroup(hGroup);
56  // Not loaded
57  return false;
58 }
#define _MAX_FNAME_LEN
void SReplaceChar(char *str, char fc, char tc)
Definition: Standard.cpp:354
void FinishLoad(const StdStrBuf &, C4Group &hGroup)
bool LoadEntryString(const char *entry_name, StdStrBuf *buffer)
Definition: C4Group.cpp:2430
char * getMData()
Definition: StdBuf.h:443
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174

References _MAX_FNAME_LEN, C4ComponentHost::Clear(), StdStrBuf::Copy(), C4ComponentHost::CopyFilePathFromGroup(), C4ComponentHost::Data, C4ComponentHost::Filename, C4ComponentHost::FinishLoad(), StdStrBuf::Format(), StdStrBuf::getData(), StdStrBuf::getMData(), C4Group::LoadEntryString(), SCopySegment(), SReplaceChar(), and SSearch().

Referenced by C4Game::CompileRuntimeData(), C4Game::InitScriptEngine(), C4ScriptHost::Load(), C4ScenarioListLoader::Entry::Load(), C4Language::LoadComponentHost(), and C4Game::LoadScenarioComponents().

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

◆ Load() [2/2]

bool C4ComponentHost::Load ( C4GroupSet hGroupSet,
const char *  szFilename,
const char *  szLanguage = nullptr 
)
inherited

Definition at line 60 of file C4ComponentHost.cpp.

63 {
64  // Clear any old stuff
65  Clear();
66  // Store filename
67  if (fname)
68  Filename.Copy(fname);
69  // Load component - try all segmented filenames
70  char strEntry[_MAX_FNAME_LEN];
71  StdStrBuf strEntryWithLanguage;
72  for (int iFilename = 0; SCopySegment(Filename.getData(), iFilename, strEntry, '|'); iFilename++)
73  {
74  // Try to insert all language codes provided into the filename
75  char strCode[3] = "";
76  for (int iLang = 0; SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2); iLang++)
77  {
78  // Insert language code
79  strEntryWithLanguage.Format(strEntry, strCode);
80  if (hGroupSet.LoadEntryString(strEntryWithLanguage, &Data))
81  {
82  C4Group *pGroup = hGroupSet.FindEntry(strEntryWithLanguage.getData());
83  FinishLoad(strEntryWithLanguage, *pGroup);
84  // Got it
85  return true;
86  }
87  // Couldn't insert language code anyway - no point in trying other languages
88  if (!SSearch(strEntry, "%s")) break;
89  }
90  }
91  // Truncate any additional segments from stored filename
92  SReplaceChar(Filename.getMData(), '|', 0);
93  // for error message purposes, the first group failed to provide the desired file
94  CopyFilePathFromGroup(*hGroupSet.GetGroup(0));
95  // Not loaded
96  return false;
97 }
bool LoadEntryString(const char *szEntryName, StdStrBuf *rBuf)
Definition: C4GroupSet.cpp:225
C4Group * GetGroup(int32_t iIndex)
Definition: C4GroupSet.cpp:259
C4Group * FindEntry(const char *szWildcard, int32_t *pPriority=nullptr, int32_t *pID=nullptr)
Definition: C4GroupSet.cpp:175

References _MAX_FNAME_LEN, C4ComponentHost::Clear(), StdStrBuf::Copy(), C4ComponentHost::CopyFilePathFromGroup(), C4ComponentHost::Data, C4ComponentHost::Filename, C4GroupSet::FindEntry(), C4ComponentHost::FinishLoad(), StdStrBuf::Format(), StdStrBuf::getData(), C4GroupSet::GetGroup(), StdStrBuf::getMData(), C4GroupSet::LoadEntryString(), SCopySegment(), SReplaceChar(), and SSearch().

Here is the call graph for this function:

◆ OnLoad()

void C4LangStringTable::OnLoad ( )
inlineoverrideprotectedvirtual

Reimplemented from C4ComponentHost.

Definition at line 50 of file C4LangStringTable.h.

50 { strings.clear(); } // Make sure we re-populate when the string table is reloaded

◆ ReplaceStrings() [1/2]

void C4LangStringTable::ReplaceStrings ( const StdStrBuf rBuf,
StdStrBuf rTarget 
)

Definition at line 91 of file C4LangStringTable.cpp.

92 {
93  if (!rBuf.getLength())
94  {
95  return;
96  }
97  // grab char ptr from buf
98  const char *Data = rBuf.getData();
99 
100  // Find Replace Positions
101  int iScriptLen = SLen(Data);
102  struct RP { const char *Pos; std::string String; unsigned int Len; RP *Next; } *pRPList = nullptr, *pRPListEnd = nullptr;
103  for (const char *pPos = SSearch(Data, "$"); pPos; pPos = SSearch(pPos, "$"))
104  {
105  // Get name
106  char szStringName[C4MaxName + 1];
107  SCopyUntil(pPos, szStringName, '$', C4MaxName); pPos += SLen(szStringName) + 1;
108  if (*(pPos-1) != '$') continue;
109  // valid?
110  const char *pPos2 = szStringName;
111  while (*pPos2)
112  if (!IsIdentifier(*(pPos2++)))
113  break;
114  if (*pPos2) continue;
115  // check termination
116  try
117  {
118  // search in string table
119  std::string pStrTblEntry = Translate(szStringName);
120  // add new replace-position entry
121  RP *pnRP = new RP;
122  pnRP->Pos = pPos - SLen(szStringName) - 2;
123  pnRP->String = pStrTblEntry;
124  pnRP->Len = SLen(szStringName) + 2;
125  pnRP->Next = nullptr;
126  pRPListEnd = (pRPListEnd ? pRPListEnd->Next : pRPList) = pnRP;
127  // calculate new script length
128  iScriptLen += pStrTblEntry.size() - pnRP->Len;
129  }
130  catch (NoSuchTranslation &)
131  {
132  LogF(R"(%s: string table entry not found: "%s")", GetFilePath() ? GetFilePath() : "<unknown>", szStringName);
133  }
134  }
135  // Alloc new Buffer
136  char *pNewBuf;
137  StdStrBuf sNewBuf;
138  sNewBuf.SetLength(iScriptLen);
139  pNewBuf = sNewBuf.getMData();
140  // Copy data
141  const char *pRPos = Data; char *pWPos = pNewBuf;
142  for (RP *pRPPos = pRPList; pRPPos; pRPPos = pRPPos->Next)
143  {
144  // copy preceding string data
145  SCopy(pRPos, pWPos, pRPPos->Pos - pRPos);
146  pWPos += pRPPos->Pos - pRPos;
147  // copy string
148  SCopyUntil(pRPPos->String.c_str(), pWPos, '\n');
149  SReplaceChar(pWPos, '\r', '\0');
150  // advance
151  pRPos = pRPPos->Pos + pRPPos->Len;
152  pWPos += SLen(pWPos);
153  }
154  SCopy(pRPos, pWPos);
155 
156  while (pRPList)
157  {
158  RP *pRP = pRPList;
159  pRPList = pRP->Next;
160  delete pRP;
161  }
162 
163  // assign this buf
164  rTarget.Clear();
165  rTarget.Take(std::move(sNewBuf));
166 }
C4String * String(const char *str)
Definition: C4AulDefFunc.h:30
const unsigned int C4MaxName
bool IsIdentifier(char cChar)
Definition: Standard.cpp:90
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
void SCopyUntil(const char *szSource, char *sTarget, char cUntil, int iMaxL, int iIndex)
Definition: Standard.cpp:172
size_t SLen(const char *sptr)
Definition: Standard.h:74
const char * GetFilePath() const
const std::string & Translate(const std::string &text) const
void SetLength(size_t iLength)
Definition: StdBuf.h:509
void Take(char *pnData)
Definition: StdBuf.h:457

References C4MaxName, StdStrBuf::Clear(), C4ComponentHost::Data, StdStrBuf::getData(), C4ComponentHost::GetFilePath(), StdStrBuf::getLength(), StdStrBuf::getMData(), IsIdentifier(), LogF(), SCopy(), SCopyUntil(), StdStrBuf::SetLength(), SLen(), SReplaceChar(), SSearch(), String(), StdStrBuf::Take(), and Translate().

Here is the call graph for this function:

◆ ReplaceStrings() [2/2]

void C4LangStringTable::ReplaceStrings ( StdStrBuf rBuf)

Definition at line 168 of file C4LangStringTable.cpp.

169 {
170  ReplaceStrings(rBuf, rBuf);
171 }
void ReplaceStrings(StdStrBuf &rBuf)

Referenced by C4MapFolderData::Load(), C4ScenarioParameterDefs::Load(), C4TeamList::Load(), C4PlayerControlFile::Load(), C4PlayerInfoList::Load(), C4ScriptHost::LoadData(), and C4ScriptHost::MakeScript().

Here is the caller graph for this function:

◆ Translate()

const std::string & C4LangStringTable::Translate ( const std::string &  text) const

Definition at line 30 of file C4LangStringTable.cpp.

31 {
32  if (strings.empty())
33  PopulateStringTable();
34  Table::const_iterator it = strings.find(text);
35  if (it == strings.end())
36  {
37  throw NoSuchTranslation(text);
38  }
39  return it->second;
40 }

References C4ScriptGuiWindowPropertyName::text.

Referenced by LoadResStr(), ReplaceStrings(), and C4ScriptHost::Translate().

Here is the caller graph for this function:

Member Data Documentation

◆ Data

◆ Filename

StdCopyStrBuf C4ComponentHost::Filename
protectedinherited

◆ FilePath

StdCopyStrBuf C4ComponentHost::FilePath
protectedinherited

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