/* * 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. */ #ifndef PG_DELIMITERS_H_ #define PG_DELIMITERS_H_ #include #pragma interface #include /* * There are (currently six) levels of delimiters for segments, * fields, repeated fields, components and sub-components. Anything can * be delimited by a \r since this is the end of the segment. A field * can be delimited by \r and |, a repeated field by \r, |, and ~ and so * on. Thus we handle delimiters as a set (actualy a string), ordered * from the lowest level (-5) of delimiter to the highest (0). Where * the highest level corresponds to the segment and the lowest to the * sub-component. * On request, we return the string from the actual level onwards. * * ASTM knows only 4 delimiters, but I don't know yet, how they relate * to HL7: * * NAME DEFAULT HL7? * "field delimiter" `|' field * "repeat field delimiter" `\' repeat? escape? * "component delimiter" `^' component * "escape delimiter" `&' escape? subcomponent? * * Anyway, we use the same delimiter ordering as in HL7, just don't read * and write all of them. If a undefined delimiter is used, it's a problem * that we can't fix here anyway (except to complain). */ class Delimiters : public PGObject { private: /* * The actual delimiters are to be set upon beginning of a message and * are valid until the message is read completely. Afterwards it should * be reloaded with the defaults. */ /* Function Default Level Position */ char _esc; /* Escape character ('\\') - 3 */ char _scm; /* Sub-Component separator ('&') -5 4 */ char _cmp; /* Component separator ('^') -4 1 */ char _rep; /* Repetition separator ('~') -3 2 */ char _fld; /* Field separator ('|') -2 5 */ char _seg; /* Segment separator ('\r') -1 - */ char __eos; /* = 0 end of string 0 */ public: enum levels { invalid = 1, toplevel = 0, msglevel = 0, /* messages are not ended by delimiters */ seglevel = -1, fldlevel = -2, replevel = -3, cmplevel = -4, scmlevel = -5, lowlevel = -5, esclevel = -6, botlevel = -6, }; typedef enum levels level_t; enum defaults { seg_def = 0x0D, fld_def = '|', cmp_def = '^', scm_def = '&', rep_def = '~', esc_def = 0134, }; Delimiters(); Delimiters(char fld, char rep, char cmp, char scm, char esc); void reset(); void unset(); bool ispresent() const; bool commit(); /* setseg(char d) is not allowed in HL7 */ void setfld(char d); void setrep(char d); void setcmp(char d); void setscm(char d); void setesc(char d); char getseg() const; char getfld() const; char getrep() const; char getcmp() const; char getscm() const; char getesc() const; result input(istream&); void output(ostream&) const; level_t levelof(char d) const; /* getdel(...) -- calculate the delimiter characters for a level * * Unfortunately this function is way outdated. The level mechanism * is not as generally applicable as it was originally intended. * * ARGUMENT 2 RETURN VALUE STRING * -------------------- ------------------------------- ----------- * esclevel all delimiters including ESC "\&^~|" * botlevel(*) " " " " "\&^~|" * (not supplied) all delimiters except ESC "&^~|" * lowlevel(*) " " " " "&^~|" * scmlevel " " " " "&^~|" * cmplevel depending on stream level: 0 "^~|" * " " " " " : -1 "&^~|" * replevel starting from REP "~|" * fldlevel starting from FLD "|" * seglevel starting from SEG "" * msglevel(*) empty string "" * toplevel(*) empty string "" * * NOTE: (*) do not use this! * * This is certainly not very intelligent, and has to be cleaned up * sometimes! FIXME! */ const char *getdel(level_t level, level_t offset) const; inline friend const char *getdel(const ios& io, level_t offset = lowlevel); }; #ifndef OUTLINE # include "Delimiters.icc" #endif #endif /* !PG_DELIMITERS_H_ */