openclonk/src/c4group/C4ComponentHost.cpp

146 lines
4.4 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
/* Holds a single text file component from a group */
#include "C4Include.h"
#include "c4group/C4ComponentHost.h"
bool C4ComponentHost::Load(C4Group &hGroup,
const char *fname,
const char *szLanguage)
{
// Clear any old stuff
Clear();
// Store filename
if (fname)
Filename.Copy(fname);
// Load component - try all segmented filenames
char strEntry[_MAX_FNAME+1];
StdStrBuf strEntryWithLanguage;
for (int iFilename = 0; SCopySegment(Filename.getData(), iFilename, strEntry, '|'); iFilename++)
{
// Try to insert all language codes provided into the filename
char strCode[3] = "";
for (int iLang = 0; SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2); iLang++)
{
// Insert language code
strEntryWithLanguage.Format(strEntry, strCode);
if (hGroup.LoadEntryString(strEntryWithLanguage, &Data))
{
FinishLoad(strEntryWithLanguage, hGroup);
// Got it
return true;
}
// Couldn't insert language code anyway - no point in trying other languages
if (!SSearch(strEntry, "%s")) break;
}
}
// Truncate any additional segments from stored filename
SReplaceChar(Filename.getMData(), '|', 0);
CopyFilePathFromGroup(hGroup);
// Not loaded
return false;
}
bool C4ComponentHost::Load(C4GroupSet &hGroupSet,
const char *fname,
const char *szLanguage)
{
// Clear any old stuff
Clear();
// Store filename
if (fname)
Filename.Copy(fname);
// Load component - try all segmented filenames
char strEntry[_MAX_FNAME+1];
StdStrBuf strEntryWithLanguage;
for (int iFilename = 0; SCopySegment(Filename.getData(), iFilename, strEntry, '|'); iFilename++)
{
// Try to insert all language codes provided into the filename
char strCode[3] = "";
for (int iLang = 0; SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2); iLang++)
{
// Insert language code
strEntryWithLanguage.Format(strEntry, strCode);
if (hGroupSet.LoadEntryString(strEntryWithLanguage, &Data))
{
C4Group *pGroup = hGroupSet.FindEntry(strEntryWithLanguage.getData());
FinishLoad(strEntryWithLanguage, *pGroup);
// Got it
return true;
}
// Couldn't insert language code anyway - no point in trying other languages
if (!SSearch(strEntry, "%s")) break;
}
}
// Truncate any additional segments from stored filename
SReplaceChar(Filename.getMData(), '|', 0);
// for error message purposes, the first group failed to provide the desired file
CopyFilePathFromGroup(*hGroupSet.GetGroup(0));
// Not loaded
return false;
}
void C4ComponentHost::FinishLoad(const StdStrBuf & name, C4Group &hGroup)
{
Data.EnsureUnicode();
// Skip those stupid "zero width no-break spaces" (also known as Byte Order Marks)
if (Data[0] == '\xEF' && Data[1] == '\xBB' && Data[2] == '\xBF')
{
Data.Move(3,Data.getSize()-3);
Data.Shrink(3);
}
// Store actual filename
hGroup.FindEntry(name.getData(), &Filename);
CopyFilePathFromGroup(hGroup);
// Notify
OnLoad();
}
// Construct full path
void C4ComponentHost::CopyFilePathFromGroup(const C4Group &hGroup)
{
FilePath.Copy(Config.AtRelativePath(hGroup.GetFullName().getData()));
FilePath.AppendBackslash();
FilePath.Append(Filename);
}
bool C4ComponentHost::GetLanguageString(const char *szLanguage, StdStrBuf &rTarget)
{
const char *cptr;
// No good parameters
if (!szLanguage || !Data) return false;
// Search for two-letter language identifier in text body, i.e. "DE:"
char langindex[4] = "";
for (int clseg=0; SCopySegment(szLanguage ? szLanguage : "", clseg, langindex, ',', 2); clseg++)
{
SAppend(":",langindex);
if ((cptr = SSearch(Data.getData(),langindex)))
{
// Return the according string
int iEndPos = SCharPos('\r', cptr);
if (iEndPos<0) iEndPos = SCharPos('\n', cptr);
if (iEndPos<0) iEndPos = strlen(cptr);
rTarget.Copy(cptr, iEndPos);
return true;
}
}
// Language string not found
return false;
}