int Dictionary::get_document_index (ustring dictionaryname) { DocMap::iterator dm = m_document_map.find(dictionaryname); int dindex; if (dm == m_document_map.end()) { dindex = m_documents.size(); m_document_map[dictionaryname] = dindex; pugi::xml_document *doc = new pugi::xml_document; m_documents.push_back (doc); pugi::xml_parse_result parse_result; if (boost::ends_with (dictionaryname.string(), ".xml")) { // xml file -- read it parse_result = doc->load_file (dictionaryname.c_str()); } else { // load xml directly from the string parse_result = doc->load_buffer (dictionaryname.c_str(), dictionaryname.length()); } if (! parse_result) { m_context->error ("XML parsed with errors: %s, at offset %d", parse_result.description(), parse_result.offset); m_document_map[dictionaryname] = -1; return -1; } } else { dindex = dm->second; } DASSERT (dindex < (int)m_documents.size()); return dindex; }
bool RendererServices::texture (ustring filename, TextureHandle *texture_handle, TexturePerthread *texture_thread_info, TextureOpt &options, ShaderGlobals *sg, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, int nchannels, float *result, float *dresultds, float *dresultdt) { ShadingContext *context = sg->context; if (! texture_thread_info) texture_thread_info = context->texture_thread_info(); bool status; if (texture_handle) status = texturesys()->texture (texture_handle, texture_thread_info, options, s, t, dsdx, dtdx, dsdy, dtdy, nchannels, result, dresultds, dresultdt); else status = texturesys()->texture (filename, options, s, t, dsdx, dtdx, dsdy, dtdy, nchannels, result, dresultds, dresultdt); if (!status) { std::string err = texturesys()->geterror(); if (err.size() && sg) { context->error ("[RendererServices::texture] %s", err); } } return status; }
int Dictionary::dict_find (ustring dictionaryname, ustring query) { int dindex = get_document_index (dictionaryname); if (dindex < 0) return dindex; ASSERT (dindex >= 0 && dindex < (int)m_documents.size()); Query q (dindex, 0, query); QueryMap::iterator qfound = m_cache.find (q); if (qfound != m_cache.end()) { return qfound->second.valueoffset; } pugi::xml_document *doc = m_documents[dindex]; // Query was not found. Do the expensive lookup and cache it pugi::xpath_node_set matches; try { matches = doc->select_nodes (query.c_str()); } catch (const pugi::xpath_exception& e) { m_context->error ("Invalid dict_find query '%s': %s", query.c_str(), e.what()); return 0; } if (matches.empty()) { m_cache[q] = QueryResult (false); // mark invalid return 0; // Not found } int firstmatch = (int) m_nodes.size(); int last = -1; for (int i = 0, e = (int)matches.size(); i < e; ++i) { m_nodes.push_back (Node (dindex, matches[i].node())); int nodeid = (int) m_nodes.size()-1; if (last < 0) { // If this is the first match, add a cache entry for it m_cache[q] = QueryResult (true /* it's a node */, nodeid); } else { // If this is a subsequent match, set the last match's 'next' m_nodes[last].next = nodeid; } last = nodeid; } return firstmatch; }
int Dictionary::dict_find (int nodeID, ustring query) { if (nodeID <= 0 || nodeID >= (int)m_nodes.size()) return 0; // invalid node ID const Dictionary::Node &node (m_nodes[nodeID]); Query q (node.document, nodeID, query); QueryMap::iterator qfound = m_cache.find (q); if (qfound != m_cache.end()) { return qfound->second.valueoffset; } // Query was not found. Do the expensive lookup and cache it pugi::xpath_node_set matches; try { matches = node.node.select_nodes (query.c_str()); } catch (const pugi::xpath_exception& e) { m_context->error ("Invalid dict_find query '%s': %s", query.c_str(), e.what()); return 0; } if (matches.empty()) { m_cache[q] = QueryResult (false); // mark invalid return 0; // Not found } int firstmatch = (int) m_nodes.size(); int last = -1; for (int i = 0, e = (int)matches.size(); i < e; ++i) { m_nodes.push_back (Node (node.document, matches[i].node())); int nodeid = (int) m_nodes.size()-1; if (last < 0) { // If this is the first match, add a cache entry for it m_cache[q] = QueryResult (true /* it's a node */, nodeid); } else { // If this is a subsequent match, set the last match's 'next' m_nodes[last].next = nodeid; } last = nodeid; } return firstmatch; }