bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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
36static char rcsid[] not_used = "$Id$";
37
38
39#include <cstdlib>
40#include <string>
41
42#include <libdap/AttrTable.h>
43#include <libdap/Error.h>
44#include <libdap/dods-datatypes.h>
45#include <libdap/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
51DODS_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\
82day_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
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//
virtual DODS_Date get()