bes  Updated for version 3.20.6
DODS_Date_Factory.cc
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of ff_handler a FreeForm API handler for the OPeNDAP
5 // DAP2 data server.
6 
7 // Copyright (c) 2005 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This is free software; you can redistribute it and/or modify it under the
11 // terms of the GNU Lesser General Public License as published by the Free
12 // Software Foundation; either version 2.1 of the License, or (at your
13 // option) any later version.
14 //
15 // This software is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 // License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 // (c) COPYRIGHT URI/MIT 1998
27 // Please read the full copyright statement in the file COPYRIGHT.
28 //
29 // Authors:
30 // jhrg,jimg James Gallagher (jgallagher@gso.uri.edu)
31 
32 // Implementation of the DODS_Date_Factory class
33 
34 #include "config_ff.h"
35 
36 static char rcsid[] not_used = "$Id$";
37 
38 
39 #include <cstdlib>
40 #include <string>
41 
42 #include <AttrTable.h>
43 #include <Error.h>
44 #include <dods-datatypes.h>
45 #include <dods-limits.h>
46 
47 #include "DODS_Date_Factory.h"
48 #include "util_ff.h"
49 
50 // attribute_name defaults to "DODS_Date." 1/21/2002 jhrg
51 DODS_Date_Factory::DODS_Date_Factory(DDS &dds, const string &attribute_name)
52 {
53  // Read the names of the variables which encode year, month and
54  // day from the DAS. These are contained in the DODS_Date attribute
55  // container.
56 
57  AttrTable *at = dds.get_attr_table().find_container(attribute_name);
58  if (!at)
59  throw Error(unknown_error,
60  string("DODS_Date_Factory requires that the ")
61  + attribute_name
62  + string("DODS_Date attribute be present."));
63 
64  string year_name = at->get_attr("year_variable");
65  string year_base = at->get_attr("year_base");
66  string month_name = at->get_attr("month_variable");
67  string day_name = at->get_attr("day_variable");
68  string year_day_name = at->get_attr("year_day_variable");
69  string month_day_name = at->get_attr("month_day_const");
70 
71  // Check to see if these dates are ymd or yd type dates.
72 
73  if (year_day_name == "" && day_name != "")
74  _format = ymd;
75  else if (year_day_name != "" && day_name == "")
76  _format = yd;
77  else if (year_day_name == "" && day_name == "")
78  _format = ym;
79  else
80  throw Error(unknown_error,
81 "DODS_Date_Factory requires that one, and only one, of the attributes\n\
82 day_variable or year_day_variable be present.");
83 
84  // Extract year_base if it's present, else set year base to zero.
85 
86  if (year_base == "")
87  _year_base = 0; // changed NULL to 0. 5/23/2001 jhrg
88  else {
89  const char *c = year_base.c_str();
90  char *c2;
91  _year_base = strtol(c, &c2, 0);
92  if (c == c2 || _year_base == DODS_LONG_MAX || _year_base == DODS_LONG_MIN)
93  throw Error(unknown_error,
94 "The year_base attribute value cannot be converted to a valid integer.");
95  }
96 
97  // Extract month_day if it's present, else set month_day to 15 (default).
98 
99  _month_day = 15;
100  if (_format == ym && month_day_name != "")
101  {
102  const char *c = month_day_name.c_str();
103  char *c2;
104  _month_day = strtol(c, &c2, 0);
105  if (c == c2 || _month_day == DODS_LONG_MAX || _month_day == DODS_LONG_MIN)
106  throw Error(unknown_error,
107 "The month_day attribute value cannot be converted to a valid integer.");
108  }
109 
110  // Now check that these variables actually exist and that they have
111  // sensible types.
112 
113  _year = dds.var(year_name);
114  if ((_year->type() != dods_int16_c) && (_year->type() != dods_uint16_c) &&
115  (_year->type() != dods_int32_c) && (_year->type() != dods_uint32_c))
116  throw Error(unknown_error, "DODS_Date_Factory: The variable used for the year must be an integer.");
117 
118  switch (_format) {
119  case ymd: {
120  _month = dds.var(month_name);
121  if (!is_integer_type(_month))
122  throw Error(unknown_error,
123 "DODS_Date_Factory: The variable used for the month must be an integer.");
124 
125  _day = dds.var(day_name);
126  if (!is_integer_type(_day))
127  throw Error(unknown_error,
128 "DODS_Date_Factory: The variable used for days must be an integer.");
129  _year_day = NULL;
130  break;
131  }
132 
133  case yd: {
134  _month = NULL;
135  _day = NULL;
136  _year_day = dds.var(year_day_name);
137  if (!is_integer_type(_year))
138  throw Error(unknown_error,
139 "DODS_Date_Factory: The variable used for the year-day must be an integer.");
140  break;
141  }
142  case ym: {
143  _month = dds.var(month_name);
144  if (!is_integer_type(_month))
145  throw Error(unknown_error,
146  "DODS_Date_Factory: The variable used for the month must be an integer.");
147  _day = NULL;
148  _year_day = NULL;
149  break;
150  }
151 
152  default:
153  throw Error(unknown_error,
154 "DODS_Date_Factory: Not able to figure out the date format.");
155  break;
156  }
157 }
158 
159 DODS_Date
161 {
162  dods_uint32 year = get_integer_value(_year);
163 
164  switch (_format) {
165  case ymd: {
166  dods_uint32 month = get_integer_value(_month);
167  dods_uint32 day = get_integer_value(_day);
168 
169  return DODS_Date(year + _year_base, month, day);
170  break;
171  }
172 
173  case yd: {
174  dods_uint32 year_day = get_integer_value(_year_day);
175 
176  return DODS_Date(year + _year_base, year_day);
177  break;
178  }
179 
180  case ym: {
181  dods_uint32 month = get_integer_value(_month);
182 
183  int day = _month_day;
184  date_format fmt = ym;
185 
186  return DODS_Date(year + _year_base, month, day, fmt);
187  break;
188  }
189 
190  default:
191  throw Error(unknown_error,
192 "DODS_Date_Factory: Unknown date format, should never get here!");
193  }
194 }
195 
196 // $Log: DODS_Date_Factory.cc,v $
197 // Revision 1.6 2003/02/10 23:01:52 jimg
198 // Merged with 3.2.5
199 //
200 // Revision 1.5 2001/09/28 23:19:43 jimg
201 // Merged with 3.2.3.
202 //
203 // Revision 1.4.2.3 2002/01/22 02:19:35 jimg
204 // Fixed bug 62. Users built fmt files that used types other than int32
205 // for date and time components (e.g. int16). I fixed the factory classes
206 // so that DODS_Date and DODS_Time objects will be built correctly when
207 // any of the integer (or in the case of seconds, float) data types are
208 // used. In so doing I also refactored the factory classes so that code
209 // duplication was reduced (by using inhertiance).
210 // Added two tests for the new capabilities (see date_time.1.exp, the last
211 // two tests).
212 //
213 // Revision 1.4.2.2 2001/05/23 19:04:31 jimg
214 // Changed NULL to 0 in an assignment to _year_base (which is an int) because
215 // of a g++ warning.
216 //
217 // Revision 1.4.2.1 2001/05/23 18:26:20 dan
218 // Modified to support year/month date representations,
219 // and to support ISO8601 output formats.
220 //
221 // Revision 1.4 2000/10/11 19:37:55 jimg
222 // Moved the CVS log entries to the end of files.
223 // Changed the definition of the read method to match the dap library.
224 // Added exception handling.
225 // Added exceptions to the read methods.
226 //
227 // Revision 1.3 2000/08/31 22:16:53 jimg
228 // Merged with 3.1.7
229 //
230 // Revision 1.2.8.1 2000/08/03 20:18:57 jimg
231 // Removed config_dap.h and replaced it with config_ff.h (in *.cc files;
232 // neither should be included in a header file).
233 // Changed code that calculated leap year information so that it uses the
234 // functions in date_proc.c/h.
235 //
236 // Revision 1.2 1999/05/04 02:55:35 jimg
237 // Merge with no-gnu
238 //
239 // Revision 1.1.10.1 1999/05/01 04:50:20 brent
240 // converted old String.h to the new std C++ <string> code
241 //
242 // Revision 1.1 1999/01/22 20:44:34 jimg
243 // Added
244 //
DODS_Date_Factory::get
virtual DODS_Date get()
Definition: DODS_Date_Factory.cc:160
DODS_Date
Definition: DODS_Date.h:108
Error