libdap++  Updated for version 3.11.7
Keywords2.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2011 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 #include "config.h"
25 
26 static char rcsid[] not_used = { "$Id: ResponseBuilder.cc 23477 2010-09-02 21:02:59Z jimg $" };
27 
28 #include <iostream>
29 #include <vector>
30 
31 //#define DODS_DEBUG
32 
33 #include "Keywords2.h"
34 #include "Error.h"
35 #include "escaping.h"
36 #include "debug.h"
37 
38 using namespace std;
39 
40 namespace libdap {
41 
42 Keywords::Keywords()
43 {
44  // Load known keywords and their allowed values
45  vector<string> v1(7);
46  v1[0] = "2"; v1[1] = "2.0"; v1[2] = "3.2"; v1[3] = "3.3"; v1[4] = "3.4";
47  v1[5] = "4"; v1[6] = "4.0";
48  value_set_t vs = value_set_t(v1.begin(), v1.end());
49  d_known_keywords["dap"] = vs;
50 
51  vector<string> v2(4);
52  v2[0] = "md5"; v2[1] = "MD5"; v2[2] = "sha1"; v2[3] = "SHA1";
53  value_set_t vs2 = value_set_t(v2.begin(), v2.end());
54  d_known_keywords["checksum"] = vs2;
55 }
56 
57 Keywords::~Keywords()
58 {
59 }
60 
68 static bool f_parse_keyword(const string &kw, string &word, string &value)
69 {
70  word = "";
71  value = "";
72  string::size_type i = kw.find('(');
73  if (i == string::npos)
74  return false;
75  word = kw.substr(0, i);
76  string::size_type j = kw.find(')');
77  if (j == string::npos)
78  return false;
79  ++i; // Move past the opening brace
80  value = kw.substr(i, j-i);
81 
82  return (!word.empty() && !value.empty());
83 }
84 
91 void Keywords::m_add_keyword(const keyword &word, const keyword_value &value)
92 {
93  d_parsed_keywords[word] = value;
94 }
95 
103 bool Keywords::m_is_valid_keyword(const keyword &word, const keyword_value &value) const
104 {
105  map<keyword, value_set_t>::const_iterator ci = d_known_keywords.find(word);
106  if (ci == d_known_keywords.end())
107  return false;
108  else {
109  value_set_t vs = ci->second;
110 
111  if (vs.find(value) == vs.end())
112  throw Error("Bad value passed to the keyword/function: " + word);
113  }
114 
115  return true;
116 }
117 
123 bool Keywords::is_known_keyword(const string &word) const
124 {
125  return d_known_keywords.count(word) == 1;
126 }
127 
133 list<Keywords::keyword> Keywords::get_keywords() const
134 {
135  list<keyword> kws;
136  map<keyword, keyword_value>::const_iterator i;
137  for (i = d_parsed_keywords.begin(); i != d_parsed_keywords.end(); ++i)
138  kws.push_front((*i).first);
139 
140  return kws;
141 }
142 
143 
150 bool Keywords::has_keyword(const keyword &kw) const
151 {
152  return d_parsed_keywords.count(kw) == 1;
153 }
154 
160 Keywords::keyword_value Keywords::get_keyword_value(const keyword &kw) const
161 {
162  if (d_known_keywords.find(kw) == d_known_keywords.end())
163  throw Error("Keyword not known (" + kw + ")");
164 
165  return d_parsed_keywords.find(kw)->second;
166 }
167 
173 string Keywords::parse_keywords(const string &ce)
174 {
175  // Get the whole CE
176  string projection = www2id(ce, "%", "%20");
177  string selection = "";
178 
179  // Separate the selection part (which follows/includes the first '&')
180  string::size_type amp = projection.find('&');
181  if (amp != string::npos) {
182  selection = projection.substr(amp);
183  projection = projection.substr(0, amp);
184  }
185 
186  // Extract keywords; add to the Keywords keywords. For this, scan for
187  // a known set of keywords and assume that anything else is part of the
188  // projection and should be left alone. Keywords must come before variables
189  // The 'projection' string will look like: '' or 'dap4.0' or 'dap4.0,u,v'
190  while (!projection.empty()) {
191  string::size_type i = projection.find(',');
192  string next_word = projection.substr(0, i);
193  string word, value;
194  if (f_parse_keyword(next_word, word, value)
195  && m_is_valid_keyword(word, value)) {
196  m_add_keyword(word, value);
197  if (i != string::npos)
198  projection = projection.substr(i + 1);
199  else
200  projection = "";
201  }
202  else {
203  break; // exit on first non-keyword
204  }
205  }
206 
207  // The CE is whatever is left after removing the keywords
208  return projection + selection;
209 }
210 
211 }
#define not_used
Definition: config.h:853
string keyword
Definition: Keywords2.h:55
string www2id(const string &in, const string &escape, const string &except)
Definition: escaping.cc:218
set< keyword_value > value_set_t
Definition: Keywords2.h:57
string keyword_value
Definition: Keywords2.h:56
A class for error processing.
Definition: Error.h:90