/* * 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("@(#) Composite.cc (Gunther Schadow) 12/19/96"); #pragma implementation #include "Composite.h" #include "DataTypeCode.h" #include "xios.h" #include "Delimiters.h" #include "misc.h" #include "exception.h" #include "logfile.h" #include "ParseTrace.h" #define ITEM(i) ( & ( this ->* itemtab[i].memberp ) ) void Composite::unset() { LOGDEBUG("unset %styp", (const char *)DataTypeCode((DataTypeCode::Value)type())); int i; for(i=0; iunset(); Type::unset(); } void Composite::nullify() { LOGDEBUG("nullify %styp", (const char *)DataTypeCode((DataTypeCode::Value)type())); int i; for(i=0; iunset(); Type::nullify(); } bool Composite::OK() const { LOGDEBUG("check %styp", (const char *)DataTypeCode((DataTypeCode::Value)type())); int i; for(i=0; iOK()) return FALSE; return Type::OK(); } bool Composite::commit() { LOGDEBUG("commit %styp", (const char *)DataTypeCode((DataTypeCode::Value)type())); int i; bool isset = FALSE; for(i=0; icommit() || isset; if(isset) set(); else if(ispresent()) unset(); // enforce a valid state return isset; } result Composite::input(istream& is) { CompositeTracer tracer((DataTypeCode::Value)type()); LOGDEBUG("input %styp", (const char *)DataTypeCode((DataTypeCode::Value)type())); if(isdebug(is)) FATAL("can't read from debug stream"); const char *dset = getdel(is, Delimiters::cmplevel); // any composite member must use a subcomponent delimiter Delimiters::level_t currlevel = level(is); setlevel(is, (Delimiters::level_t)(currlevel - 1)); bool eoc_seen = FALSE; int i; for(i=0; itype()); if(eoc_seen) item->unset(); else { item->input(is); eoc_seen = !match(is, dset); } if(i==0 && eoc_seen) // if there is nothing but the first item { if(!item->ispresent()) // and it is not present `||' { unset(); // the whole composite object is absent goto finish; } if(item->isnull()) // or it is null `|""|' { nullify(); // the whole composite object is null goto finish; } } } set(); finish: // reset the level to normal setlevel(is, currlevel); return SUCCESS; } void Composite::output(ostream& os) const { LOGDEBUG("output %styp", (const char *)DataTypeCode((DataTypeCode::Value)type())); if(ishl7er(os) || isastmer(os)) { if(ispresent()) { char eoc = *getdel(os, Delimiters::cmplevel); // any composite member must use a subcomponent delimiter Delimiters::level_t currlevel = level(os); setlevel(os, (Delimiters::level_t)(currlevel - 1)); int i = 0; while(ioutput(os); if(i==noitems) break; os << eoc; } // reset the level to normal setlevel(os, currlevel); } } else /* debug output */ { if(ispresent()) { int i=0; while(ioutput(os); if(i==noitems) break; os << DSSEPR; } } else os << DSNOPS; os << DSEGRP; } }