forked from Mirrors/openclonk
146 lines
4.4 KiB
C++
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;
|
|
}
|