std::string russ_format(const std::string& format_str, const LLSD& context) { std::string service_url(format_str); if(!service_url.empty() && context.isMap()) { // throw in a ridiculously large limiter to make sure we don't // loop forever with bad input. int iterations = 100; bool keep_looping = true; while(keep_looping) { if(0 == --iterations) { keep_looping = false; } int depth = 0; int deepest = 0; bool find_match = false; std::string::iterator iter(service_url.begin()); std::string::iterator end(service_url.end()); std::string::iterator deepest_node(service_url.end()); std::string::iterator deepest_node_end(service_url.end()); // parse out the variables to replace by going through {}s // one at a time, starting with the "deepest" in series // {{}}, and otherwise replacing right-to-left for(; iter != end; ++iter) { switch(*iter) { case '{': ++depth; if(depth > deepest) { deepest = depth; deepest_node = iter; find_match = true; } break; case '}': --depth; if(find_match) { deepest_node_end = iter; find_match = false; } break; default: break; } } if((deepest_node == end) || (deepest_node_end == end)) { break; } //replace the variable we found in the {} above. // *NOTE: since the c++ implementation only understands // params and straight string substitution, so it's a // known distance of 2 to skip the directive. std::string key(deepest_node + 2, deepest_node_end); LLSD value = context[key]; switch(*(deepest_node + 1)) { case '$': if(value.isDefined()) { service_url.replace( deepest_node, deepest_node_end + 1, value.asString()); } else { llwarns << "Unknown key: " << key << " in option map: " << LLSDOStreamer<LLSDNotationFormatter>(context) << llendl; keep_looping = false; } break; case '%': { std::string query_str = LLURI::mapToQueryString(value); service_url.replace( deepest_node, deepest_node_end + 1, query_str); } break; default: llinfos << "Unknown directive: " << *(deepest_node + 1) << llendl; keep_looping = false; break; } } } if (service_url.find('{') != std::string::npos) { llwarns << "Constructed a likely bogus service URL: " << service_url << llendl; } return service_url; }
/////////////////////////////////////////// // subtree_height(bp *b,i64 s) // returns the height of the subtree of s // 0 if s is a leaf /////////////////////////////////////////// i64 subtree_height(bp *b,i64 s) { i64 t; t = deepest_node(b,s); return depth(b,t) - depth(b,s); }