/* * 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("@(#) ANYseg.cc (Gunther Schadow) 12/19/96"); #pragma implementation #include "ANYseg.h" #include "logfile.h" #include "exception.h" #include "xios.h" #include "ParseTrace.h" #include "ANYseg-config.h" ANYseg::ANYseg(const ANYseg &x) : PGObject(PGObject::anyseg, 0) { _allowed = x._allowed; _frozen = FALSE; SegTypeCode::Value st = x.type(); switch (st) { ANYSEG_CASES(_seg); default: FATAL("illegal segment type %d", st); /* no, FATAL does not return */ } *_seg=*x._seg; } const ANYseg & ANYseg::operator = (const ANYseg &x) { _allowed = x._allowed; SegTypeCode::Value st = x.type(); if(_seg != NULL && !_frozen) { delete _seg; _seg = NULL; } _frozen = FALSE; switch (st) { ANYSEG_CASES(_seg); default: FATAL("illegal segment type %d", st); /* no, FATAL does not return */ } *_seg=*x._seg; return *this; } void ANYseg::unset() { if(_seg != NULL) delete _seg; _seg = NULL; _frozen = FALSE; } bool ANYseg::ispresent() const { if(_seg != NULL) return _seg->ispresent(); else return FALSE; } SegTypeCode::Value ANYseg::type() const { if(_seg != NULL) return (SegTypeCode::Value)_seg->type(); else return SegTypeCode::invalid; } const ANYseg& ANYseg::operator = (const Segment &x) { SegTypeCode::Value st = x.type(); if(_allowed.test(st)) { if(_seg != NULL) delete _seg; switch (st) { ANYSEG_CASES(_seg) default: goto illegal; } *_seg=x; return *this; } illegal: FATAL("illegal segment type %d", st); /* no, FATAL does not return */ } Segment* const ANYseg::operator -> () const { if(_seg != NULL) return _seg; else FATAL("segment pointer is NULL"); /* no, FATAL does not return */ } Segment& ANYseg::operator * () const { if(_seg != NULL) return *_seg; else FATAL("segment pointer is NULL"); /* no, FATAL does not return */ } ANYseg::operator Segment & () const { if(_seg != NULL) return *_seg; else FATAL("segment pointer is NULL"); /* no, FATAL does not return */ } result ANYseg::input(istream& is) { SegmentTracer tracer; if(istouched(is)) FATAL("can't read from a touched stream"); /* no, FATAL does not return */ streammarker spos(is.rdbuf()); // remember the stream position int taglen; if(ishl7er(is)) taglen = 4; else if(isastmer(is)) taglen = 2; else if(isdebug(is)) FATAL("can't read from a debug stream"); LOGDEBUG("hl7/astm"); char sid[taglen]; is.get(sid, taglen); if(*sid == '\0') { if(is.eof()) { LOGDEBUG("end of stream"); return FAIL; } else ERROS("error on input stream"); } SegTypeCode st(sid); if(st==SegTypeCode::invalid || st==SegTypeCode::null) { record_parse_error("invalid segment id `%s'", sid); EPARSE("invalid segment id `%s'", sid); } if(!_allowed.test(st)) goto unexpected; if(_seg != NULL) delete _seg; is >> touch; switch(st) { ANYSEG_CASES(_seg) default: goto unexpected; } if(_seg->input(is) == SUCCESS) { lprintf(L_JUNK, "ANYseg::input: finished successfully"); return SUCCESS; } else FATAL("input failed on touched stream (while reading %d)", (int)st); /* no, FATAL does not return */ unexpected: LOGWARNING("unexpected segment %d, backtracking ...", (int)st); unset(); is.rdbuf()->seekmark(spos); /* restore old stream position */ return FAIL; } bool ANYseg::OK() const { if(_seg != NULL) return _seg->OK(); else return TRUE; } bool ANYseg::commit() { if(_seg != NULL) return _seg->commit(); else return FALSE; }