X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Furl_recipe.cpp;h=9cd21b091a03cf16da34c656f21a2a9e077ef5ef;hb=3b4860c163303e7a0c2ecc3946c4053cb6c72714;hp=bba6a41353c71aa1177da40d4d0717dbb184db3e;hpb=a5fe7e6104de3fccbbbe7cb57253b261b0ac6ecc;p=metaproxy-moved-to-github.git diff --git a/src/url_recipe.cpp b/src/url_recipe.cpp index bba6a41..9cd21b0 100644 --- a/src/url_recipe.cpp +++ b/src/url_recipe.cpp @@ -1,5 +1,5 @@ /* This file is part of Metaproxy. - Copyright (C) 2005-2011 Index Data + Copyright (C) 2005-2013 Index Data Metaproxy is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -16,77 +16,148 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.hpp" + +#include +#include #include #include -namespace mp = metaproxy_1; -// Doxygen doesn't like mp::xml, so we use this instead namespace mp_xml = metaproxy_1::xml; -void mp_xml::url_recipe_handle(xmlDoc *doc, std::string recipe) +std::string mp_xml::url_recipe_handle(xmlDoc *doc, std::string recipe) { - if (recipe.length() == 0) - return; std::string result; + if (recipe.length() == 0) + return result; - size_t p0 = 0, p1 = 0; - for (;;) + const xmlNode *ptr1 = xmlDocGetRootElement(doc); + while (ptr1 && ptr1->type != XML_ELEMENT_NODE) + ptr1 = ptr1->next; + if (ptr1) + ptr1 = ptr1->children; + + size_t p0 = 0; + while (p0 < recipe.length()) { - p1 = recipe.find_first_of("${", p0); - if (p1 == std::string::npos) + bool uri_encode = false; + if (p0 < recipe.length() -1 && recipe[p0] == '%' + && recipe[p0 + 1] == '{') { - result += recipe.substr(p0); - break; + p0++; + p0++; + uri_encode = true; + } + else if (p0 < recipe.length() -1 && recipe[p0] == '$' + && recipe[p0 + 1] == '{') + { + p0++; + p0++; + } + else + { + result += recipe[p0]; + p0++; + continue; } - result += recipe.substr(p0, p1 - p0); - int step = 0; // 0=variable, 1=pattern, 2=replacement, 3=mode std::string variable; std::string pattern; std::string replacement; std::string mode; - p0 = p1+2; + int c_prev = 0; while (p0 < recipe.length() && step < 5) { char c = recipe[p0]; - if (c == '}') + int c_check = c; + if (c_prev == '\\') + c_check = 0; + + if (c_check == '}') step = 5; else if (step == 0) { - if (c == '[') + if (c_check == '[') step = 1; else variable += c; } + else if (c_check == ']') + step = 4; else if (step == 1) { - if (c == '/') + if (c_check == '/') step = 2; else pattern += c; } else if (step == 2) { - if (c == '/') + if (c_check == '/') step = 3; else replacement += c; } else if (step == 3) { - if (c == ']') - step = 4; - else - mode += c; + mode += c; } + c_prev = c; p0++; } if (variable.length()) { - ; + std::string text; + size_t offset = 0; + size_t md_pos = variable.find_first_of("md-"); + if (md_pos == 0) + offset = 3; + const xmlNode *ptr = ptr1; + for (; ptr; ptr = ptr->next) + if (ptr->type == XML_ELEMENT_NODE + && !strcmp((const char *) ptr->name, "metadata")) + { + const _xmlAttr *attr = ptr->properties; + for (; attr; attr = attr->next) + if (!strcmp((const char *) attr->name, "type") + && attr->children + && !strcmp((const char *) attr->children->content, + variable.c_str() + offset)) + { + text = mp_xml::get_text(ptr); + break; + } + } + if (pattern.length() > 0) + { + boost::regex::flag_type b_mode = boost::regex::perl; + if (mode.find_first_of('i') != std::string::npos) + b_mode |= boost::regex::icase; + boost::regex e(pattern, b_mode); + boost::match_flag_type match_mode = boost::format_first_only; + if (mode.find_first_of('g') != std::string::npos) + match_mode = boost::format_all; + text = regex_replace(text, e, replacement, match_mode); + } + if (!uri_encode) + result += text; + else + { + char src[2]; + char dst[4]; + size_t i; + for (i = 0; i < text.length(); i++) + { + src[0] = text[i]; + src[1] = '\0'; + yaz_encode_uri_component(dst, src); + result += dst; + } + } } } + return result; }