libdap++
Updated for version 3.8.2
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 // 00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00024 #include "config.h" 00025 00026 static char rcsid[] not_used = { "$Id: ResponseBuilder.cc 23477 2010-09-02 21:02:59Z jimg $" }; 00027 00028 #include <iostream> 00029 #include <vector> 00030 00031 //#define DODS_DEBUG 00032 00033 #include "Keywords2.h" 00034 #include "Error.h" 00035 #include "escaping.h" 00036 #include "debug.h" 00037 00038 using namespace std; 00039 00040 namespace libdap { 00041 00042 Keywords::Keywords() 00043 { 00044 // Load known keywords and their allowed values 00045 vector<string> v1(7); 00046 v1[0] = "2"; v1[1] = "2.0"; v1[2] = "3.2"; v1[3] = "3.3"; v1[4] = "3.4"; 00047 v1[5] = "4"; v1[6] = "4.0"; 00048 value_set_t vs = value_set_t(v1.begin(), v1.end()); 00049 d_known_keywords["dap"] = vs; 00050 00051 vector<string> v2(4); 00052 v2[0] = "md5"; v2[1] = "MD5"; v2[2] = "sha1"; v2[3] = "SHA1"; 00053 value_set_t vs2 = value_set_t(v2.begin(), v2.end()); 00054 d_known_keywords["checksum"] = vs2; 00055 } 00056 00057 Keywords::~Keywords() 00058 { 00059 } 00060 00068 static bool f_parse_keyword(const string &kw, string &word, string &value) 00069 { 00070 word = ""; 00071 value = ""; 00072 string::size_type i = kw.find('('); 00073 if (i == string::npos) 00074 return false; 00075 word = kw.substr(0, i); 00076 string::size_type j = kw.find(')'); 00077 if (j == string::npos) 00078 return false; 00079 ++i; // Move past the opening brace 00080 value = kw.substr(i, j-i); 00081 00082 return (!word.empty() && !value.empty()); 00083 } 00084 00091 void Keywords::m_add_keyword(const keyword &word, const keyword_value &value) 00092 { 00093 d_parsed_keywords[word] = value; 00094 } 00095 00103 bool Keywords::m_is_valid_keyword(const keyword &word, const keyword_value &value) const 00104 { 00105 map<keyword, value_set_t>::const_iterator ci = d_known_keywords.find(word); 00106 if (ci == d_known_keywords.end()) 00107 return false; 00108 else { 00109 value_set_t vs = ci->second; 00110 00111 if (vs.find(value) == vs.end()) 00112 throw Error("Bad value passed to the keyword/function: " + word); 00113 } 00114 00115 return true; 00116 } 00117 00123 bool Keywords::is_known_keyword(const string &word) const 00124 { 00125 return d_known_keywords.count(word) == 1; 00126 } 00127 00133 list<Keywords::keyword> Keywords::get_keywords() const 00134 { 00135 list<keyword> kws; 00136 map<keyword, keyword_value>::const_iterator i; 00137 for (i = d_parsed_keywords.begin(); i != d_parsed_keywords.end(); ++i) 00138 kws.push_front((*i).first); 00139 00140 return kws; 00141 } 00142 00143 00150 bool Keywords::has_keyword(const keyword &kw) const 00151 { 00152 return d_parsed_keywords.count(kw) == 1; 00153 } 00154 00160 Keywords::keyword_value Keywords::get_keyword_value(const keyword &kw) const 00161 { 00162 if (d_known_keywords.find(kw) == d_known_keywords.end()) 00163 throw Error("Keyword not known (" + kw + ")"); 00164 00165 return d_parsed_keywords.find(kw)->second; 00166 } 00167 00173 string Keywords::parse_keywords(const string &ce) 00174 { 00175 // Get the whole CE 00176 string projection = www2id(ce, "%", "%20"); 00177 string selection = ""; 00178 00179 // Separate the selection part (which follows/includes the first '&') 00180 string::size_type amp = projection.find('&'); 00181 if (amp != string::npos) { 00182 selection = projection.substr(amp); 00183 projection = projection.substr(0, amp); 00184 } 00185 00186 // Extract keywords; add to the Keywords keywords. For this, scan for 00187 // a known set of keywords and assume that anything else is part of the 00188 // projection and should be left alone. Keywords must come before variables 00189 // The 'projection' string will look like: '' or 'dap4.0' or 'dap4.0,u,v' 00190 while (!projection.empty()) { 00191 string::size_type i = projection.find(','); 00192 string next_word = projection.substr(0, i); 00193 string word, value; 00194 if (f_parse_keyword(next_word, word, value) 00195 && m_is_valid_keyword(word, value)) { 00196 m_add_keyword(word, value); 00197 if (i != string::npos) 00198 projection = projection.substr(i + 1); 00199 else 00200 projection = ""; 00201 } 00202 else { 00203 break; // exit on first non-keyword 00204 } 00205 } 00206 00207 // The CE is whatever is left after removing the keywords 00208 return projection + selection; 00209 } 00210 00211 }