/* * 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. */ /* * Supplements for the GNU libg++/iostream library. Allowing to have * lines be terminated by a character from a set (char *delim). * * With the esc char handling that isn't used in HL7 * * These are just simple hacks on the original GNU libg++-2.4.1 sources * * NOTE: Please solve the `FIXME's before you relay on this module! */ #include "pg_config.h" #include "ioext.h" //#include "support.h" #include #include /* FROM sbgetline.cc */ long sgetline(streambuf& sb, char* buf, _IO_size_t n, const char *delim, int extract_delim, char esc) { return _IO_getline_dsete(&sb, buf, n, delim, extract_delim, esc); } /* FROM: isgetline.cc */ #define CHUNK_SIZE 512 /* Reads an arbitrarily long input line terminated by user-specified * TERMINATORs, protectable by a user-specified escape character. * Super-nifty trick using recursion avoids unnecessary calls * to NEW! */ char *_sb_readline (streambuf *sb, long& total, const char *terminator, char esc) { char buf[CHUNK_SIZE+1]; char *ptr; int ch; long count = sgetline(*sb, buf, CHUNK_SIZE+1, terminator, -1, esc); if (count == EOF) return NULL; ch = sb->sgetc(); // sb->sbumpc(); long old_total = total; total += count; /* FIXME!! * We do not care for escape characters here, this is certainly * not correct even though it seems to work. Before this isn't * proved it *will* be a cause of failor sometimes. */ if (ch != EOF && !strchr(terminator,ch)) { total++; // Include ch in total. sb->sbumpc(); ptr = _sb_readline(sb, total, terminator, esc); if (ptr) { memcpy(ptr + old_total, buf, count); ptr[old_total+count] = ch; } return ptr; } if ((ptr = new char[total+1])) { ptr[total] = '\0'; memcpy(ptr + total - count, buf, count); return ptr; } else return NULL; } /* Reads an arbitrarily long input line terminated by any char * in the string `delim' which is not preceeded by an esc char. * This routine allocates its own memory, so the user should * only supply the address of a (char *). */ char *gets(istream& is, const char *delim, char esc) { char *s; size_t _gcount; if (is.ipfx1()) { long size = 0; streambuf *sb = is.rdbuf(); s = _sb_readline (sb, size, delim, esc); _gcount = s ? size : 0; if (sb->_flags & _IO_EOF_SEEN) { is.set(ios::eofbit); if (_gcount == 0) is.set(ios::failbit); } } else { _gcount = 0; s = NULL; } return s; }