// called for each matching directory entry; add its full pathname to array. static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData) { BuildDirEntListState* s = (BuildDirEntListState*)cbData; jsval val = ScriptInterface::ToJSVal(s->cx, CStrW(pathname.string())); JS_SetElement(s->cx, s->filename_array, s->cur_idx++, &val); return INFO::OK; }
// called for each matching directory entry; add its full pathname to array. static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData) { BuildDirEntListState* s = (BuildDirEntListState*)cbData; JS::RootedValue val(s->cx); ScriptInterface::ToJSVal( s->cx, val.get(), CStrW(pathname.string()) ); JS_SetElement(s->cx, s->filename_array, s->cur_idx++, val.address()); return INFO::OK; }
void AtlasViewGame::SetParam(const std::wstring& name, const std::wstring& value) { if (name == L"passability") { m_DisplayPassability = CStrW(value).ToUTF8(); CmpPtr<ICmpObstructionManager> cmpObstructionManager(*GetSimulation2(), SYSTEM_ENTITY); if (cmpObstructionManager) cmpObstructionManager->SetDebugOverlay(!value.empty()); CmpPtr<ICmpPathfinder> cmpPathfinder(*GetSimulation2(), SYSTEM_ENTITY); if (cmpPathfinder) cmpPathfinder->SetDebugOverlay(!value.empty()); } else if (name == L"renderpath") { g_Renderer.SetRenderPath(g_Renderer.GetRenderPathByName(CStrW(value).ToUTF8())); } }
// called for each matching directory entry; add its full pathname to array. static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData) { BuildDirEntListState* s = (BuildDirEntListState*)cbData; JSAutoRequest rq(s->cx); JS::RootedObject filenameArrayObj(s->cx, s->filename_array); JS::RootedValue val(s->cx); ScriptInterface::ToJSVal( s->cx, &val, CStrW(pathname.string()) ); JS_SetElement(s->cx, filenameArrayObj, s->cur_idx++, val); return INFO::OK; }
void CConsole::SaveHistory() { WriteBuffer buffer; const int linesToSkip = (int)m_deqBufHistory.size() - m_MaxHistoryLines; std::deque<std::wstring>::reverse_iterator it = m_deqBufHistory.rbegin(); if(linesToSkip > 0) std::advance(it, linesToSkip); for (; it != m_deqBufHistory.rend(); ++it) { CStr8 line = CStrW(*it).ToUTF8(); buffer.Append(line.data(), line.length()); static const char newline = '\n'; buffer.Append(&newline, 1); } g_VFS->CreateFile(m_sHistoryFile, buffer.Data(), buffer.Size()); }
void CGUIString::SetValue(const CStrW& str) { m_OriginalString = str; // clear m_TextChunks.clear(); m_Words.clear(); m_RawString = CStrW(); // Setup parser // TODO Gee: (2004-08-16) Create and store this parser object somewhere to save loading time. // TODO PT: Extended CParserCache so that the above is possible (since it currently only // likes one-task parsers) CParser Parser; // I've added the option of an additional parameter. Only used for icons when writing this. Parser.InputTaskType("start", "$ident[_=_$value_[$ident_=_$value_]]"); Parser.InputTaskType("end", "/$ident"); long position = 0; long from=0; // the position in the raw std::string where the last tag ended long from_nonraw=0; // like from only in position of the REAL std::string, with tags. long curpos = 0; // Current Text Chunk CGUIString::TextChunk CurrentTextChunk; for (;;position = curpos+1) { // Find next TagStart character curpos = str.Find(position, TagStart); if (curpos == -1) { m_RawString += str.substr(position); if (from != (long)m_RawString.length()) { CurrentTextChunk.m_From = from; CurrentTextChunk.m_To = (int)m_RawString.length(); m_TextChunks.push_back(CurrentTextChunk); } break; } else { // First check if there is another TagStart before a TagEnd, // in that case it's just a regular TagStart and we can continue. long pos_left = str.Find(curpos+1, TagStart); long pos_right = str.Find(curpos+1, TagEnd); if (pos_right == -1) { m_RawString += str.substr(position, curpos-position+1); continue; } else if (pos_left != -1 && pos_left < pos_right) { m_RawString += str.substr(position, pos_left-position); continue; } else { m_RawString += str.substr(position, curpos-position); // Okay we've found a TagStart and TagEnd, positioned // at pos and pos_right. Now let's extract the // interior and try parsing. CStrW tagstr (str.substr(curpos+1, pos_right-curpos-1)); CParserLine Line; Line.ParseString(Parser, tagstr.ToUTF8()); // Set to true if the tag is just text. bool justtext = false; if (Line.m_ParseOK) { if (Line.m_TaskTypeName == "start") { // The tag TextChunk::Tag tag; std::string Str_TagType; Line.GetArgString(0, Str_TagType); if (!tag.SetTagType(Str_TagType)) { justtext = true; } else { // Check for possible value-std::strings if (Line.GetArgCount() >= 2) Line.GetArgString(1, tag.m_TagValue); //Handle arbitrary number of additional parameters size_t argn; for(argn = 2; argn < Line.GetArgCount(); argn += 2) { TextChunk::Tag::TagAttribute a; Line.GetArgString(argn, a.attrib); Line.GetArgString(argn+1, a.value); tag.m_TagAttributes.push_back(a); } // Finalize last if (curpos != from_nonraw) { CurrentTextChunk.m_From = from; CurrentTextChunk.m_To = from + curpos - from_nonraw; m_TextChunks.push_back(CurrentTextChunk); from = CurrentTextChunk.m_To; } from_nonraw = pos_right+1; // Some tags does not have a closure, and should be // stored without text. Like a <tag /> in XML. if (tag.m_TagType == TextChunk::Tag::TAG_IMGLEFT || tag.m_TagType == TextChunk::Tag::TAG_IMGRIGHT || tag.m_TagType == TextChunk::Tag::TAG_ICON) { // We need to use a fresh text chunk // because 'tag' should be the *only* tag. TextChunk FreshTextChunk; // They does not work with the text system. FreshTextChunk.m_From = from + pos_right+1 - from_nonraw; FreshTextChunk.m_To = from + pos_right+1 - from_nonraw; FreshTextChunk.m_Tags.push_back(tag); m_TextChunks.push_back(FreshTextChunk); } else { // Add that tag, but first, erase previous occurences of the // same tag. std::vector<TextChunk::Tag>::iterator it; for (it = CurrentTextChunk.m_Tags.begin(); it != CurrentTextChunk.m_Tags.end(); ++it) { if (it->m_TagType == tag.m_TagType) { CurrentTextChunk.m_Tags.erase(it); break; } } // Add! CurrentTextChunk.m_Tags.push_back(tag); } } } else if (Line.m_TaskTypeName == "end") { // The tag TextChunk::Tag tag; std::string Str_TagType; Line.GetArgString(0, Str_TagType); if (!tag.SetTagType(Str_TagType)) { justtext = true; } else { // Finalize the previous chunk if (curpos != from_nonraw) { CurrentTextChunk.m_From = from; CurrentTextChunk.m_To = from + curpos - from_nonraw; m_TextChunks.push_back(CurrentTextChunk); from = CurrentTextChunk.m_To; } from_nonraw = pos_right+1; // Search for the tag, if it's not added, then // pass it as plain text. std::vector<TextChunk::Tag>::iterator it; for (it = CurrentTextChunk.m_Tags.begin(); it != CurrentTextChunk.m_Tags.end(); ++it) { if (it->m_TagType == tag.m_TagType) { CurrentTextChunk.m_Tags.erase(it); break; } } } } } else justtext = true; if (justtext) { // What was within the tags could not be interpreted // so we'll assume it's just text. m_RawString += str.substr(curpos, pos_right-curpos+1); } curpos = pos_right; continue; } } } // Add a delimiter at start and at end, it helps when // processing later, because we don't have make exceptions for // those cases. // We'll sort later. m_Words.push_back(0); m_Words.push_back((int)m_RawString.length()); // Space: ' ' for (position=0, curpos=0;;position = curpos+1) { // Find the next word-delimiter. long dl = m_RawString.Find(position, ' '); if (dl == -1) break; curpos = dl; m_Words.push_back((int)dl+1); } // Dash: '-' for (position=0, curpos=0;;position = curpos+1) { // Find the next word-delimiter. long dl = m_RawString.Find(position, '-'); if (dl == -1) break; curpos = dl; m_Words.push_back((int)dl+1); } // New Line: '\n' for (position=0, curpos=0;;position = curpos+1) { // Find the next word-delimiter. long dl = m_RawString.Find(position, '\n'); if (dl == -1) break; curpos = dl; // Add before and m_Words.push_back((int)dl); m_Words.push_back((int)dl+1); } sort(m_Words.begin(), m_Words.end()); // Remove duplicates (only if larger than 2) if (m_Words.size() > 2) { std::vector<int>::iterator it; int last_word = -1; for (it = m_Words.begin(); it != m_Words.end(); ) { if (last_word == *it) { it = m_Words.erase(it); } else { last_word = *it; ++it; } } } #if 0 for (int i=0; i<(int)m_Words.size(); ++i) { LOGMESSAGE(L"m_Words[%d] = %d", i, m_Words[i]); } for (int i=0; i<(int)m_TextChunks.size(); ++i) { LOGMESSAGE(L"m_TextChunk[%d] = [%d,%d]", i, m_TextChunks[i].m_From, m_TextChunks[i].m_To); for (int j=0; j<(int)m_TextChunks[i].m_Tags.size(); ++j) { LOGMESSAGE(L"--Tag: %d \"%hs\"", (int)m_TextChunks[i].m_Tags[j].m_TagType, m_TextChunks[i].m_Tags[j].m_TagValue.c_str()); } } #endif }
template <> void XMLWriter_Element::Text<const wchar_t*>(const wchar_t* text, bool cdata) { Text( CStrW(text).ToUTF8().c_str(), cdata ); }
void CParamNode::ApplyLayer(const XMBFile& xmb, const XMBElement& element, const wchar_t* sourceIdentifier /*= NULL*/) { ResetScriptVal(); std::string name = xmb.GetElementString(element.GetNodeName()); // TODO: is GetElementString inefficient? CStrW value = element.GetText().FromUTF8(); bool hasSetValue = false; // Look for special attributes int at_disable = xmb.GetAttributeID("disable"); int at_replace = xmb.GetAttributeID("replace"); int at_op = xmb.GetAttributeID("op"); int at_datatype = xmb.GetAttributeID("datatype"); enum op { INVALID, ADD, MUL } op = INVALID; bool replacing = false; { XERO_ITER_ATTR(element, attr) { if (attr.Name == at_disable) { m_Childs.erase(name); return; } else if (attr.Name == at_replace) { m_Childs.erase(name); replacing = true; } else if (attr.Name == at_op) { if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"add") op = ADD; else if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"mul") op = MUL; else LOGWARNING("Invalid op '%ls'", attr.Value); } } } { XERO_ITER_ATTR(element, attr) { if (attr.Name == at_datatype && std::wstring(attr.Value.begin(), attr.Value.end()) == L"tokens") { CParamNode& node = m_Childs[name]; // Split into tokens std::vector<std::wstring> oldTokens; std::vector<std::wstring> newTokens; if (!replacing && !node.m_Value.empty()) // ignore the old tokens if replace="" was given boost::algorithm::split(oldTokens, node.m_Value, boost::algorithm::is_space(), boost::algorithm::token_compress_on); if (!value.empty()) boost::algorithm::split(newTokens, value, boost::algorithm::is_space(), boost::algorithm::token_compress_on); // Merge the two lists std::vector<std::wstring> tokens = oldTokens; for (size_t i = 0; i < newTokens.size(); ++i) { if (newTokens[i][0] == L'-') { std::vector<std::wstring>::iterator tokenIt = std::find(tokens.begin(), tokens.end(), newTokens[i].substr(1)); if (tokenIt != tokens.end()) tokens.erase(tokenIt); else LOGWARNING("[ParamNode] Could not remove token '%s' from node '%s'%s; not present in list nor inherited (possible typo?)", utf8_from_wstring(newTokens[i].substr(1)), name, sourceIdentifier ? (" in '" + utf8_from_wstring(sourceIdentifier) + "'").c_str() : ""); } else { if (std::find(oldTokens.begin(), oldTokens.end(), newTokens[i]) == oldTokens.end()) tokens.push_back(newTokens[i]); } } node.m_Value = boost::algorithm::join(tokens, L" "); hasSetValue = true; break; } } } // Add this element as a child node CParamNode& node = m_Childs[name]; if (op != INVALID) { // TODO: Support parsing of data types other than fixed; log warnings in other cases fixed oldval = node.ToFixed(); fixed mod = fixed::FromString(CStrW(value)); switch (op) { case ADD: node.m_Value = (oldval + mod).ToString().FromUTF8(); break; case MUL: node.m_Value = (oldval.Multiply(mod)).ToString().FromUTF8(); break; } hasSetValue = true; } if (!hasSetValue) node.m_Value = value; // We also need to reset node's script val, even if it has no children // or if the attributes change. node.ResetScriptVal(); // Recurse through the element's children XERO_ITER_EL(element, child) { node.ApplyLayer(xmb, child, sourceIdentifier); }