+
+
+inline bool CNodeDefManager::getNodeRegistrationStatus() const
+{
+ return m_node_registration_complete;
+}
+
+
+inline void CNodeDefManager::setNodeRegistrationStatus(bool completed)
+{
+ m_node_registration_complete = completed;
+}
+
+
+void CNodeDefManager::pendNodeResolve(NodeResolver *nr)
+{
+ nr->m_ndef = this;
+ if (m_node_registration_complete)
+ nr->nodeResolveInternal();
+ else
+ m_pending_resolve_callbacks.push_back(nr);
+}
+
+
+bool CNodeDefManager::cancelNodeResolveCallback(NodeResolver *nr)
+{
+ size_t len = m_pending_resolve_callbacks.size();
+ for (size_t i = 0; i != len; i++) {
+ if (nr != m_pending_resolve_callbacks[i])
+ continue;
+
+ len--;
+ m_pending_resolve_callbacks[i] = m_pending_resolve_callbacks[len];
+ m_pending_resolve_callbacks.resize(len);
+ return true;
+ }
+
+ return false;
+}
+
+
+void CNodeDefManager::runNodeResolveCallbacks()
+{
+ for (size_t i = 0; i != m_pending_resolve_callbacks.size(); i++) {
+ NodeResolver *nr = m_pending_resolve_callbacks[i];
+ nr->nodeResolveInternal();
+ }
+
+ m_pending_resolve_callbacks.clear();
+}
+
+
+void CNodeDefManager::resetNodeResolveState()
+{
+ m_node_registration_complete = false;
+ m_pending_resolve_callbacks.clear();
+}
+
+
+////
+//// NodeResolver
+////
+
+NodeResolver::NodeResolver()
+{
+ m_ndef = NULL;
+ m_nodenames_idx = 0;
+ m_nnlistsizes_idx = 0;
+ m_resolve_done = false;
+
+ m_nodenames.reserve(16);
+ m_nnlistsizes.reserve(4);
+}
+
+
+NodeResolver::~NodeResolver()
+{
+ if (!m_resolve_done && m_ndef)
+ m_ndef->cancelNodeResolveCallback(this);
+}
+
+
+void NodeResolver::nodeResolveInternal()
+{
+ m_nodenames_idx = 0;
+ m_nnlistsizes_idx = 0;
+
+ resolveNodeNames();
+ m_resolve_done = true;
+
+ m_nodenames.clear();
+ m_nnlistsizes.clear();
+}
+
+
+bool NodeResolver::getIdFromNrBacklog(content_t *result_out,
+ const std::string &node_alt, content_t c_fallback)
+{
+ if (m_nodenames_idx == m_nodenames.size()) {
+ *result_out = c_fallback;
+ errorstream << "NodeResolver: no more nodes in list" << std::endl;
+ return false;
+ }
+
+ content_t c;
+ std::string name = m_nodenames[m_nodenames_idx++];
+
+ bool success = m_ndef->getId(name, c);
+ if (!success && node_alt != "") {
+ name = node_alt;
+ success = m_ndef->getId(name, c);
+ }
+
+ if (!success) {
+ errorstream << "NodeResolver: failed to resolve node name '" << name
+ << "'." << std::endl;
+ c = c_fallback;
+ }
+
+ *result_out = c;
+ return success;
+}
+
+
+bool NodeResolver::getIdsFromNrBacklog(std::vector<content_t> *result_out,
+ bool all_required, content_t c_fallback)
+{
+ bool success = true;
+
+ if (m_nnlistsizes_idx == m_nnlistsizes.size()) {
+ errorstream << "NodeResolver: no more node lists" << std::endl;
+ return false;
+ }
+
+ size_t length = m_nnlistsizes[m_nnlistsizes_idx++];
+
+ while (length--) {
+ if (m_nodenames_idx == m_nodenames.size()) {
+ errorstream << "NodeResolver: no more nodes in list" << std::endl;
+ return false;
+ }
+
+ content_t c;
+ std::string &name = m_nodenames[m_nodenames_idx++];
+
+ if (name.substr(0,6) != "group:") {
+ if (m_ndef->getId(name, c)) {
+ result_out->push_back(c);
+ } else if (all_required) {
+ errorstream << "NodeResolver: failed to resolve node name '"
+ << name << "'." << std::endl;
+ result_out->push_back(c_fallback);
+ success = false;
+ }
+ } else {
+ std::set<content_t> cids;
+ std::set<content_t>::iterator it;
+ m_ndef->getIds(name, cids);
+ for (it = cids.begin(); it != cids.end(); ++it)
+ result_out->push_back(*it);
+ }
+ }
+
+ return success;
+}