00001 // Copyright (C) 2006, Vesta Free Software Project 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 #include <assert.h> 00020 #include <iosfwd> 00021 #include <iostream> 00022 #include "FP.H" 00023 00024 namespace FP { 00025 class FPStreambuf : public std::streambuf 00026 { 00027 public: 00028 #if defined(__GNUC__) && (__GNUC__ < 3) 00029 typedef streampos pos_type; 00030 typedef streamoff off_type; 00031 typedef ios::seek_dir seekdir; 00032 typedef int openmode; 00033 #else 00034 typedef std::streambuf::pos_type pos_type; 00035 typedef std::streambuf::off_type off_type; 00036 typedef std::ios_base::seekdir seekdir; 00037 typedef std::ios_base::openmode openmode; 00038 #endif 00039 00040 private: 00041 union { 00042 // Really we just want to make sure that the character array is 00043 // word-aligned 00044 Word unused; 00045 char bytes[sizeof(Word)]; 00046 } buf; 00047 00048 FP::Tag tag; 00049 00050 void flush(); 00051 00052 unsigned int total_bytes; 00053 00054 public: 00055 FPStreambuf(); 00056 FPStreambuf(const FP::Tag &init_tag); 00057 00058 inline const FP::Tag &get_tag() throw() 00059 { 00060 this->flush(); 00061 return this->tag; 00062 } 00063 00064 pos_type seekoff(off_type offset, 00065 seekdir way, 00066 openmode mode=(std::ios::in| 00067 std::ios::out)); 00068 pos_type seekpos(pos_type pos, 00069 openmode mode=(std::ios::in| 00070 std::ios::out)); 00071 00072 protected: 00073 int underflow(); 00074 std::streamsize xsgetn(char* s, std::streamsize n); 00075 int overflow(int c); 00076 std::streamsize xsputn(const char* s, std::streamsize n); 00077 }; 00078 00079 class FPStreamBase : virtual public std::ios 00080 { 00081 protected: 00082 FPStreambuf my_buf; 00083 public: 00084 FPStreamBase() 00085 : my_buf() 00086 { 00087 } 00088 FPStreamBase(const FP::Tag &init_tag) 00089 : my_buf(init_tag) 00090 { 00091 } 00092 FPStreambuf *rdbuf() { return &my_buf; } 00093 }; 00094 00095 class FPStream : public FPStreamBase, public std::ostream 00096 { 00097 public: 00098 FPStream() 00099 : FPStreamBase(), 00100 std::ostream(&my_buf) 00101 { } 00102 FPStream(const FP::Tag &init_tag) 00103 : FPStreamBase(init_tag), 00104 std::ostream(&my_buf) 00105 { } 00106 00107 inline const FP::Tag &tag() 00108 { 00109 return my_buf.get_tag(); 00110 } 00111 }; 00112 00113 }