libdap
Updated for version 3.17.0
|
00001 // -*- mode: c++; c-basic-offset:4 -*- 00002 00003 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 00004 // Access Protocol. 00005 00006 // Copyright (c) 2011 OPeNDAP, Inc. 00007 // Author: James Gallagher <jgallagher@opendap.org> 00008 // 00009 // This library is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU Lesser General Public 00011 // License as published by the Free Software Foundation; either 00012 // version 2.1 of the License, or (at your option) any later version. 00013 // 00014 // This library is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 // Lesser General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU Lesser General Public 00020 // License along with this library; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 // 00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00024 #include "config.h" 00025 00026 #include <iostream> 00027 #include <vector> 00028 00029 //#define DODS_DEBUG 00030 00031 #include "Keywords2.h" 00032 #include "Error.h" 00033 #include "escaping.h" 00034 #include "debug.h" 00035 00036 using namespace std; 00037 00038 namespace libdap { 00039 00040 Keywords::Keywords() 00041 { 00042 // Load known keywords and their allowed values 00043 vector<string> v1(7); 00044 v1[0] = "2"; v1[1] = "2.0"; v1[2] = "3.2"; v1[3] = "3.3"; v1[4] = "3.4"; 00045 v1[5] = "4"; v1[6] = "4.0"; 00046 value_set_t vs = value_set_t(v1.begin(), v1.end()); 00047 d_known_keywords["dap"] = vs; 00048 00049 vector<string> v2(4); 00050 v2[0] = "md5"; v2[1] = "MD5"; v2[2] = "sha1"; v2[3] = "SHA1"; 00051 value_set_t vs2 = value_set_t(v2.begin(), v2.end()); 00052 d_known_keywords["checksum"] = vs2; 00053 } 00054 00055 Keywords::~Keywords() 00056 { 00057 } 00058 00066 static bool f_parse_keyword(const string &kw, string &word, string &value) 00067 { 00068 word = ""; 00069 value = ""; 00070 string::size_type i = kw.find('('); 00071 if (i == string::npos) 00072 return false; 00073 word = kw.substr(0, i); 00074 string::size_type j = kw.find(')'); 00075 if (j == string::npos) 00076 return false; 00077 ++i; // Move past the opening paren 00078 value = kw.substr(i, j-i); 00079 00080 return (!word.empty() && !value.empty()); 00081 } 00082 00089 void Keywords::m_add_keyword(const keyword &word, const keyword_value &value) 00090 { 00091 d_parsed_keywords[word] = value; 00092 } 00093 00101 bool Keywords::m_is_valid_keyword(const keyword &word, const keyword_value &value) const 00102 { 00103 map<keyword, value_set_t>::const_iterator ci = d_known_keywords.find(word); 00104 if (ci == d_known_keywords.end()) 00105 return false; 00106 else { 00107 value_set_t vs = ci->second; 00108 00109 if (vs.find(value) == vs.end()) 00110 throw Error("Bad value passed to the keyword/function: " + word); 00111 } 00112 00113 return true; 00114 } 00115 00121 bool Keywords::is_known_keyword(const string &word) const 00122 { 00123 return d_known_keywords.count(word) == 1; 00124 } 00125 00131 list<Keywords::keyword> Keywords::get_keywords() const 00132 { 00133 list<keyword> kws; 00134 map<keyword, keyword_value>::const_iterator i; 00135 for (i = d_parsed_keywords.begin(); i != d_parsed_keywords.end(); ++i) 00136 kws.push_front((*i).first); 00137 00138 return kws; 00139 } 00140 00141 00148 bool Keywords::has_keyword(const keyword &kw) const 00149 { 00150 return d_parsed_keywords.count(kw) == 1; 00151 } 00152 00158 Keywords::keyword_value Keywords::get_keyword_value(const keyword &kw) const 00159 { 00160 if (d_known_keywords.find(kw) == d_known_keywords.end()) 00161 throw Error("Keyword not known (" + kw + ")"); 00162 00163 return d_parsed_keywords.find(kw)->second; 00164 } 00165 00171 string Keywords::parse_keywords(const string &ce) 00172 { 00173 // Get the whole CE 00174 string projection = www2id(ce, "%", "%20"); 00175 string selection = ""; 00176 00177 // Separate the selection part (which follows/includes the first '&') 00178 string::size_type amp = projection.find('&'); 00179 if (amp != string::npos) { 00180 selection = projection.substr(amp); 00181 projection = projection.substr(0, amp); 00182 } 00183 00184 // Extract keywords; add to the Keywords keywords. For this, scan for 00185 // a known set of keywords and assume that anything else is part of the 00186 // projection and should be left alone. Keywords must come before variables 00187 // The 'projection' string will look like: '' or 'dap4.0' or 'dap4.0,u,v' 00188 while (!projection.empty()) { 00189 string::size_type i = projection.find(','); 00190 string next_word = projection.substr(0, i); 00191 string word, value; 00192 if (f_parse_keyword(next_word, word, value) 00193 && m_is_valid_keyword(word, value)) { 00194 m_add_keyword(word, value); 00195 if (i != string::npos) 00196 projection = projection.substr(i + 1); 00197 else 00198 projection = ""; 00199 } 00200 else { 00201 break; // exit on first non-keyword 00202 } 00203 } 00204 00205 // The CE is whatever is left after removing the keywords 00206 return projection + selection; 00207 } 00208 00209 }