/* Copyright (c) 1997-2006 Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany) http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de 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, or (at your option) any later version: http://www.gnu.org/licenses/gpl.txt. 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. */ #ifndef _POLYMAKE_CHARBUFFER_H #define _POLYMAKE_CHARBUFFER_H "$Project: polymake $$Id: CharBuffer.h 7461 2006-11-12 23:25:23Z gawrilow $" #include #include #include #include namespace pm { class CharBuffer : public std::streambuf_with_input_width { private: // never create CharBuffer(); ~CharBuffer(); public: typedef std::streambuf::traits_type traits_type; typedef std::streambuf::int_type int_type; static void skip_all(std::streambuf *_buf) { CharBuffer *buf=static_cast(_buf); PM_SET_BUF_GET_CUR_END(buf); } static int seek_forward(std::streambuf *_buf, int offset) { CharBuffer *buf=static_cast(_buf); const int_type eof_char=traits_type::eof(); if (buf->gptr()+offset >= buf->egptr() && buf->underflow()==eof_char) return eof_char; return buf->gptr()[offset]; } static int next_ws(std::streambuf *_buf, int offset=0, bool report_eof=true) { CharBuffer *buf=static_cast(_buf); const int_type eof_char=traits_type::eof(); for (int_type c; (c=seek_forward(buf, offset))!=eof_char; ++offset) if (isspace(c)) return offset; return report_eof ? -1 : offset; } static int next_non_ws(std::streambuf *_buf, int offset=0) { CharBuffer *buf=static_cast(_buf); const int_type eof_char=traits_type::eof(); for (int_type c; (c=seek_forward(buf, offset))!=eof_char; ++offset) if (!isspace(c)) return offset; return -1; } static int skip_ws(std::streambuf *_buf) { CharBuffer *buf=static_cast(_buf); int i=next_non_ws(buf); if (i<0) { skip_all(buf); return -1; } else { buf->gbump(i); return 0; } } static int find_char_forward(std::streambuf *_buf, char c, int offset=0) { CharBuffer *buf=static_cast(_buf); const int_type eof_char=traits_type::eof(); if (seek_forward(buf, offset) != eof_char) { do { if (char *found=(char*)memchr(buf->gptr()+offset, c, buf->egptr()-(buf->gptr()+offset))) return found-buf->gptr(); offset=buf->egptr()-buf->gptr(); } while (buf->underflow() != eof_char); } return -1; } static int_type ignore(std::streambuf *_buf, char c) { CharBuffer *buf=static_cast(_buf); const int_type eof_char=traits_type::eof(); int_type next_c; while ((next_c=seek_forward(buf,0)) != eof_char) { if (next_c==c) { buf->gbump(1); break; } if (char *found=(char*)memchr(buf->gptr(), c, buf->egptr()-buf->gptr())) { buf->gbump(found-buf->gptr()+1); return c; } PM_SET_BUF_GET_CUR_END(buf); } return next_c; } static int find_string_forward(std::streambuf *_buf, const char *c, int len, int offset) { CharBuffer *buf=static_cast(_buf); const int_type eof_char=traits_type::eof(); while ((offset=find_char_forward(buf, c[0], offset)) >= 0 && seek_forward(buf, offset+len-1) != eof_char) { if (!memcmp(buf->gptr()+offset, c, len)) return offset; ++offset; } return -1; } static int count_char(std::streambuf *_buf, char c) { CharBuffer *buf=static_cast(_buf); char *start=buf->gptr(), *end=buf->egptr(); int cnt=0; while ((start=(char*)memchr(start, c, end-start)) != 0) { ++cnt; ++start; } return cnt; } static int count_lines(std::streambuf *buf) { if (skip_ws(buf)<0) return 0; return count_char(buf,'\n'); } static int matching_brace (std::streambuf *buf, char opening, char closing, int offset=0); static int get_string(std::streambuf *buf, std::string&, char delim); static char* get_ptr(std::streambuf *_buf) { CharBuffer *buf=static_cast(_buf); return buf->gptr(); } static char* end_get_ptr(std::streambuf *_buf) { CharBuffer *buf=static_cast(_buf); return buf->egptr(); } static void get_bump(std::streambuf *_buf, int offset) { CharBuffer *buf=static_cast(_buf); buf->gbump(offset); } static void set_end_get_ptr(std::streambuf *_buf, char *end) { CharBuffer *buf=static_cast(_buf); PM_SET_BUF_GET_END(buf,end); } static void set_end_get_ptr(std::streambuf *_buf, int offset) { CharBuffer *buf=static_cast(_buf); PM_SET_BUF_GET_END_OFF(buf,offset); } static void set_get_and_end_ptr(std::streambuf *_buf, char *get, char *end) { CharBuffer *buf=static_cast(_buf); PM_SET_BUF_GET_CUR(buf,get,end); } static const char* get_input_limit(std::streambuf *_buf) { return static_cast(_buf)->input_limit; } }; } // end namespace pm #endif // _POLYMAKE_CHARBUFFER_H // Local Variables: // mode:C++ // End: