/* * 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; }