/* * Copyright (c) 1995, 1996 Gunther Schadow. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "pg_config.h" IDENT("@(#) NMtyp.cc (Gunther Schadow) 08/21/95"); #pragma implementation #include "NMtyp.h" #include "logfile.h" #include "exception.h" #include "xios.h" #include "ioext.h" #include #include #include #include "STtyp.h" #include "IDtyp.h" #include "DataTypeCode.h" #include #include #include "ParseTrace.h" /* * DATA TYPE * * NM() -- numeric value */ NMtyp::NMtyp() : Primtype(DataTypeCode::NMval) { _is_float = FALSE; _int = 0; _precision = 0; } NMtyp::NMtyp(int x) : Primtype(DataTypeCode::NMval) { _is_float = FALSE; _int = x; _precision = 0; Primtype::set(); } NMtyp::NMtyp(long x) : Primtype(DataTypeCode::NMval) { _is_float = FALSE; _int = x; _precision = 0; Primtype::set(); } NMtyp::NMtyp(unsigned int x) : Primtype(DataTypeCode::NMval) { _is_float = FALSE; _int = x; _precision = 0; Primtype::set(); } NMtyp::NMtyp(double x, int prec) : Primtype(DataTypeCode::NMval) { _is_float = TRUE; _float = x; _precision = prec; Primtype::set(); } NMtyp::NMtyp(const char *s) : Primtype(DataTypeCode::NMval) { _is_float = FALSE; _int = 0; _precision = 0; if(s != NULL) { if(*s == '\0') nullify(); else { istrstream is(s); xios xis(is); input(is); } } } const NMtyp& NMtyp::operator = (long x) { _is_float = FALSE; _int = x; Primtype::set(); return *this; } const NMtyp& NMtyp::operator = (double x) { _is_float = TRUE; _float = x; _precision = 0; Primtype::set(); return *this; } const NMtyp& NMtyp::operator = (const char *s) { if(s == NULL) unset(); else if(*s == '\0') nullify(); else { istrstream is(s); xios xis(is); input(is); } return *this; } bool NMtyp::isfloat() { if(ispresent() && !isnull()) return _is_float; else FATAL("access into non-present object"); } bool NMtyp::isint() { if(ispresent() && !isnull()) return !_is_float; else FATAL("access into non-present object"); } NMtyp::operator long() const { if(ispresent() && !isnull()) { if(_is_float) return (long)_float; else return _int; } else FATAL("access into non-present object"); } NMtyp::operator double() const { if(ispresent() && !isnull()) { if(_is_float) return _float; else return (double)_int; } else FATAL("access into non-present object"); } result NMtyp::input(istream& is) { if(!ishl7er(is)) FATAL("can't read from debug stream"); LOGDEBUG("hl7er"); char *s = gets(is, getdel(is)); if( *s == 0 ) goto is_not_present; else if( strcmp(s, NULLVAL) == 0 ) goto is_null; else { /* clear any previous error, since strtol doesn't have another way * of indicating an error */ errno = 0; char *p; long longbuf = strtol(s,&p,10); if(longbuf < 0) int sign = -1; else int sign = +1; // compute the number of significant digits char *q = strpbrk(s, "123456789"); if(p > q) _precision = p - q; else _precision = 0; if( errno == 0 ) { if( *p == 0 ) // we stopped at the end of the string { _int = longbuf; goto is_int; } else if( *p == '.' ) // fractional part follows { char *q; _float = strtod(p,&q); if( errno == 0 ) if( *q == 0 ) { _float = sign * (sign * longbuf + _float); // compute the number of significant digits if(_precision == 0) p = strpbrk(s, "123456789"); else p++; // p points to the 1/10 digit _precision += strspn(p, "0123456789"); goto is_float; } else { record_parse_error("syntax error at `%s'", p); EPARSE("syntax error at `%s'", p); } else // error occured ERROS("strtol on `%s'", s); } else // conversion stopped due to junk { record_parse_error("syntax error at `%s'", p); EPARSE("syntax error at `%s'", p); } } else // error occured if( errno == ERANGE ) // result too large, try a double { errno = 0; _float = strtod(s,&p); if( errno != 0 ) // again too large! ERROS("strtod on `%s'", s); else if( *p == 0 ) // here we go. { // compute the number of significant digits p = strpbrk(s, "123456789"); _precision += strspn(p, "0123456789"); if(*p++ == '.') _precision += strspn(p, "0123456789"); goto is_float; } else // junk found { record_parse_error("syntax error at `%s'", p); EPARSE("syntax error at `%s'", p); } } else // other errors should not occur but ... { record_parse_error("strtol on `%s'", s); EPARSE("strtol on `%s'", s); } } FATAL("how did I come to this point??"); is_null: Primtype::nullify(); goto finish; is_not_present: Primtype::unset(); goto finish; is_int: _is_float = FALSE; goto is_present; is_float: _is_float = TRUE; goto is_present; is_present: Primtype::set(); goto finish; finish: delete [] s; return SUCCESS; } void NMtyp::output(ostream& os) const { if (ishl7er(os)) { LOGDEBUG("hl7er"); if (ispresent()) { if (isnull()) os << NULLVAL; else { if (_is_float) { os.precision(_precision); os << dec << _float; } else os << dec << _int; } } } else /* debug */ { LOGDEBUG("debug"); os << DSBGR0 "NMtyp" DSBGR1; if (ispresent()) if (isnull()) os << DSNULL; else if (_is_float) { os.precision(_precision); os << DSFRST "float" DSSEPR << dec << _float; } else os << DSFRST "int" DSSEPR << dec << _int; else os << DSNOPS; os << DSEGRP; } } NMtyp::operator STtyp () const return st { if (ispresent()) { char buf[128]; if (isnull()) buf[0] = '\0'; else { ostrstream os(buf, 128); if (_is_float) { os.precision(_precision); os << _float << '\0'; } else os << _int << '\0'; } st = buf; } } NMtyp::operator IDtyp () const return st { if (ispresent()) { char buf[128]; if (isnull()) buf[0] = '\0'; else { ostrstream os(buf, 128); if (_is_float) { os.precision(_precision); os << _float << '\0'; } else os << _int << '\0'; } st = buf; } }