95#ifdef COMPUTE_ENDIAN_AT_RUNTIME
98 char *c =
reinterpret_cast<char *
>(&i);
126 "The CE Evaluator built an argument list where some constants held no values.");
128 return static_cast<Str *
>(arg)->value();
131template <
class T>
static void set_array_using_double_helper(Array *a,
double *src,
int src_len) {
136 vector<T> values(src_len);
137 for (
int i = 0; i < src_len; ++i)
138 values[i] = (T)src[i];
141 a->set_value(values, src_len);
172 throw InternalErr(__FILE__, __LINE__,
"The function requires a numeric-type array argument.");
178 if (dest->
length() != src_len)
180 "The source and destination array sizes don't match (" +
long_to_string(src_len) +
189 set_array_using_double_helper<dods_byte>(dest, src, src_len);
192 set_array_using_double_helper<dods_uint16>(dest, src, src_len);
195 set_array_using_double_helper<dods_int16>(dest, src, src_len);
198 set_array_using_double_helper<dods_uint32>(dest, src, src_len);
201 set_array_using_double_helper<dods_int32>(dest, src, src_len);
204 set_array_using_double_helper<dods_float32>(dest, src, src_len);
207 set_array_using_double_helper<dods_float64>(dest, src, src_len);
212 set_array_using_double_helper<dods_byte>(dest, src, src_len);
215 set_array_using_double_helper<dods_int8>(dest, src, src_len);
218 set_array_using_double_helper<dods_uint64>(dest, src, src_len);
221 set_array_using_double_helper<dods_int64>(dest, src, src_len);
225 "The argument list built by the CE parser contained an unsupported numeric type.");
232template <
class T>
static double *extract_double_array_helper(Array *a) {
235 int length = a->length();
240 double *dest =
new double[length];
241 for (
int i = 0; i < length; ++i)
242 dest[i] = (
double)b[i];
266 throw InternalErr(__FILE__, __LINE__,
string(
"The Array '") + a->
name() +
"'does not contain values.");
274 return extract_double_array_helper<dods_byte>(a);
276 return extract_double_array_helper<dods_uint16>(a);
278 return extract_double_array_helper<dods_int16>(a);
280 return extract_double_array_helper<dods_uint32>(a);
282 return extract_double_array_helper<dods_int32>(a);
284 return extract_double_array_helper<dods_float32>(a);
290 return extract_double_array_helper<dods_float64>(a);
294 return extract_double_array_helper<dods_byte>(a);
296 return extract_double_array_helper<dods_int8>(a);
298 return extract_double_array_helper<dods_uint64>(a);
300 return extract_double_array_helper<dods_int64>(a);
303 "The argument list built by the CE parser contained an unsupported numeric type.");
310template <
class T>
static void extract_double_array_helper(Array *a, vector<double> &dest) {
312 assert(dest.size() == (
unsigned long)a->length());
314 int length = a->length();
319 for (
int i = 0; i < length; ++i)
320 dest[i] = (
double)b[i];
346 throw InternalErr(__FILE__, __LINE__,
string(
"The Array '") + a->
name() +
"' does not contain values.");
356 return extract_double_array_helper<dods_byte>(a, dest);
358 return extract_double_array_helper<dods_uint16>(a, dest);
360 return extract_double_array_helper<dods_int16>(a, dest);
362 return extract_double_array_helper<dods_uint32>(a, dest);
364 return extract_double_array_helper<dods_int32>(a, dest);
366 return extract_double_array_helper<dods_float32>(a, dest);
368 return a->
value(dest.data());
373 return extract_double_array_helper<dods_byte>(a, dest);
375 return extract_double_array_helper<dods_int8>(a, dest);
377 return extract_double_array_helper<dods_uint64>(a, dest);
379 return extract_double_array_helper<dods_int64>(a, dest);
382 "The argument list built by the CE parser contained an unsupported numeric type.");
404 "The Evaluator built an argument list where some constants held no values.");
410 switch (arg->
type()) {
412 return (
double)(
static_cast<Byte *
>(arg)->
value());
414 return (
double)(
static_cast<UInt16 *
>(arg)->
value());
416 return (
double)(
static_cast<Int16 *
>(arg)->
value());
418 return (
double)(
static_cast<UInt32 *
>(arg)->
value());
420 return (
double)(
static_cast<Int32 *
>(arg)->
value());
424 return static_cast<Float64 *
>(arg)->value();
428 return (
double)(
static_cast<Byte *
>(arg)->
value());
430 return (
double)(
static_cast<Int8 *
>(arg)->
value());
432 return (
double)(
static_cast<UInt64 *
>(arg)->
value());
434 return (
double)(
static_cast<Int64 *
>(arg)->
value());
438 "The argument list built by the parser contained an unsupported numeric type.");
453 if (name.find_first_of(
' ') == name.npos)
457 unsigned int i = name.find_first_not_of(
' ');
458 string tmp_name = name.substr(i);
461 unsigned int j = tmp_name.find(
'?') + 1;
462 i = tmp_name.find_first_not_of(
' ', j);
463 tmp_name.erase(j, i - j);
474 vector<string> names(l.size());
477 typedef std::vector<BaseType *>::const_iterator citer;
478 for (citer i = l.begin(); i != l.end(); i++) {
480 names[nelem++] = (*i)->name();
481 DBG(cerr <<
"NAMES[" << nelem - 1 <<
"]=" << names[nelem - 1] << endl);
485 sort(names.begin(), names.end());
488 sort(names.begin(), names.end());
491 for (
int j = 1; j < nelem; ++j) {
492 if (names[j - 1] == names[j]) {
494 oss <<
"The variable `" << names[j] <<
"' is used more than once in " <<
type_name <<
" `" << var_name
527 if (time(&TimBin) == (time_t)-1)
528 return {
"time() error"};
530 char ctime_value[32];
531 const char *ret = ctime_r(&TimBin, ctime_value);
533 string TimStr = ctime_value;
534 return TimStr.substr(0, TimStr.size() - 2);
545 for (
unsigned int i = 0; i < s.length(); i++)
546 s[i] = tolower(s[i]);
554bool is_quoted(
const string &s) {
return (!s.empty() && s[0] ==
'\"' && s[s.length() - 1] ==
'\"'); }
564 return s.substr(1, s.length() - 2);
571 if (strcmp(name,
"Byte") == 0)
574 if (strcmp(name,
"Char") == 0)
577 if (strcmp(name,
"Int8") == 0)
580 if (strcmp(name,
"UInt8") == 0)
583 if (strcmp(name,
"Int16") == 0)
586 if (strcmp(name,
"UInt16") == 0)
589 if (strcmp(name,
"Int32") == 0)
592 if (strcmp(name,
"UInt32") == 0)
595 if (strcmp(name,
"Int64") == 0)
598 if (strcmp(name,
"UInt64") == 0)
601 if (strcmp(name,
"Float32") == 0)
604 if (strcmp(name,
"Float64") == 0)
607 if (strcmp(name,
"String") == 0)
613 if (strcmp(name,
"Url") == 0 || strcmp(name,
"URL") == 0)
616 if (strcmp(name,
"Enum") == 0)
619 if (strcmp(name,
"Opaque") == 0)
622 if (strcmp(name,
"Array") == 0)
625 if (strcmp(name,
"Structure") == 0)
628 if (strcmp(name,
"Sequence") == 0)
631 if (strcmp(name,
"Grid") == 0)
647 return string(
"Null");
649 return string(
"Byte");
651 return string(
"Int16");
653 return string(
"UInt16");
655 return string(
"Int32");
657 return string(
"UInt32");
659 return string(
"Float32");
661 return string(
"Float64");
663 return string(
"String");
665 return string(
"Url");
668 return string(
"Array");
670 return string(
"Structure");
672 return string(
"Sequence");
674 return string(
"Grid");
677 throw InternalErr(__FILE__, __LINE__,
"Unknown type.");
691 return string(
"Null");
693 return string(
"Byte");
695 return string(
"Char");
697 return string(
"Int8");
699 return string(
"UInt8");
701 return string(
"Int16");
703 return string(
"UInt16");
705 return string(
"Int32");
707 return string(
"UInt32");
709 return string(
"Int64");
711 return string(
"UInt64");
713 return string(
"Enum");
716 return string(
"Float32");
718 return string(
"Float64");
721 return string(
"String");
723 return string(
"URL");
726 return string(
"Opaque");
729 return string(
"Array");
732 return string(
"Structure");
734 return string(
"Sequence");
736 return string(
"Group");
739 throw InternalErr(__FILE__, __LINE__,
"Unknown type.");
915 return (stat(dir.c_str(), &buf) == 0) && (buf.st_mode & S_IFDIR);
923 char digits[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
927 if (base > 36 || base < 2) {
929 std::invalid_argument ex(
"The parameter base has an invalid value.");
934 r = ldiv(labs(val), base);
942 str_val += digits[(int)r.rem];
975static const char path_sep[] = {
"\\"};
977static const char path_sep[] = {
"/"};
989 string::size_type pos = path.rfind(path_sep);
991 return (pos == string::npos) ? path : path.substr(++pos);
994#define CHECK_BIT(tab, bit) (tab[(bit) / 8] & (1 << ((bit) % 8)))
995#define BITLISTSIZE 16
1001static void globchars(
const char *s,
const char *e,
char *b) {
1012 if (s + 2 < e && s[1] ==
'-') {
1013 for (c = s[0]; c <= s[2]; c++)
1014 b[c / 8] |= (1 << (c % 8));
1018 b[c / 8] |= (1 << (c % 8));
1049int glob(
const char *c,
const char *s) {
1069 const char *here = c;
1073 }
while (here == c || *c !=
']');
1078 globchars(here, c, bitlist);
1080 if (!
CHECK_BIT(bitlist, *(
unsigned char *)s))
1087 const char *here = s;
1100 r = *c ?
glob(c, s) : *s ? -1 : 0;
1115 if (!*c || *s != *c) {
1138bool size_ok(
unsigned int sz,
unsigned int nelem) {
return (sz > 0 && nelem < UINT_MAX / sz); }
1157 if (path.length() > 255)
1162 Regex name(
"[-0-9A-z_./]+");
1163 if (!strict) name =
"[:print:]+";
1166 const Regex strict_name(
"[-0-9A-z_./]+");
1167 const Regex relaxed_name(
"[:print:]+");
1170 string::size_type len = path.length();
1172 unsigned long result;
1174 result = strict_name.
match(path);
1176 result = relaxed_name.
match(path);
1178 return (result == path.length());
1186 if (len > INT_MAX || result !=
static_cast<int>(len))
return false;
1199 return (
string)
"OPeNDAP DAP/" +
libdap_version() +
": compiled on " + __DATE__ +
":" + __TIME__;
1216 copy(name_template.begin(), name_template.end(), back_inserter(name));
1217 if (!suffix.empty())
1218 copy(suffix.begin(), suffix.end(), back_inserter(name));
1219 name.push_back(
'\0');
1222 int tmpfile = mkstemps(name.data(), suffix.length());
1226 f.open(name.data());
1233 return string(name.data());
#define internal_error
Internal server error (500)
#define malformed_expr
(400)
A multidimensional array of identical data types.
The basic data type for the DODS DAP types.
virtual string name() const
Returns the name of the class instance.
virtual bool read_p()
Has this variable been read?
virtual bool is_simple_type() const
Returns true if the instance is a numeric, string or URL type variable.
virtual Type type() const
Returns the type of the class instance.
virtual dods_byte value() const
A class for error processing.
Holds a 32-bit floating point value.
virtual dods_float32 value() const
Holds a 64-bit (double precision) floating point value.
Holds a 16-bit signed integer value.
virtual dods_int16 value() const
Holds a 32-bit signed integer.
virtual dods_int32 value() const
Holds a64-bit signed integer.
virtual dods_int64 value() const
Holds an 8-bit signed integer value.
virtual dods_int8 value() const
A class for software fault reporting.
Regular expression matching.
int match(const char *s, int len, int pos=0) const
Does the pattern match.
Holds character string data.
Holds an unsigned 16-bit integer.
virtual dods_uint16 value() const
Holds a 32-bit unsigned integer.
virtual dods_uint32 value() const
Holds a 64-bit unsigned integer.
virtual dods_uint64 value() const
int length() const override
Returns the number of elements in the vector. Note that some child classes of Vector use the length o...
virtual void value(dods_byte *b) const
void set_read_p(bool state) override
Indicates that the data is ready to send.
BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=nullptr) override
top level DAP object to house generic methods
Type
Identifies the data type.
string open_temp_fstream(ofstream &f, const string &name_template, const string &suffix)
const char * libdap_name()
string long_to_string(long val, int base)
bool size_ok(unsigned int sz, unsigned int nelem)
sanitize the size of an array. Test for integer overflow when dynamically allocating an array.
string remove_quotes(const string &s)
void append_double_to_string(const double &num, string &str)
string path_to_filename(string path)
bool is_host_big_endian()
Does this host use big-endian byte order?
const char * libdap_version()
double extract_double_value(BaseType *arg)
string prune_spaces(const string &name)
void append_long_to_string(long val, int base, string &str_val)
void set_array_using_double(Array *dest, double *src, int src_len)
bool is_simple_type(Type t)
Returns true if the instance is a numeric, string or URL type variable.
bool dir_exists(const string &dir)
bool pathname_ok(const string &path, bool strict)
Does the string name a potentially valid pathname? Test the given pathname to verify that it is a val...
string double_to_string(const double &num)
string D2type_name(Type t)
Returns the type of the class instance as a string. Supports all DAP2 types and not the DAP4-only typ...
const char * libdap_root()
string D4type_name(Type t)
Returns the type of the class instance as a string. Supports all DAP4 types and not the DAP2-only typ...
bool is_constructor_type(Type t)
Returns true if the instance is a constructor (i.e., Structure, Sequence or Grid) type variable.
bool is_vector_type(Type t)
Returns true if the instance is a vector (i.e., array) type variable.
bool is_integer_type(Type t)
int glob(const char *c, const char *s)
string extract_string_argument(BaseType *arg)
ObjectType get_type(const string &value)
double * extract_double_array(Array *a)
bool is_quoted(const string &s)
bool unique_names(vector< BaseType * > l, const string &var_name, const string &type_name, string &msg)
#define CHECK_BIT(tab, bit)