Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

stdsstream.h

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2002 Chris Schoeneman
00004  * 
00005  * This package is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * found in the file COPYING that should have accompanied this file.
00008  * 
00009  * This package is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include "stdpre.h"
00016 
00017 #if HAVE_SSTREAM || !defined(__GNUC__) || (__GNUC__ >= 3)
00018 
00019 #include <sstream>
00020 
00021 #elif defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 95)
00022 // g++ 2.95 didn't ship with sstream.  the following is a backport
00023 // by Magnus Fromreide of the sstream in g++ 3.0.
00024 
00025 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
00026 Copyright (C) 2000 Free Software Foundation
00027 
00028 This file is part of the GNU IO Library.  This library is free
00029 software; you can redistribute it and/or modify it under the
00030 terms of the GNU General Public License as published by the
00031 Free Software Foundation; either version 2, or (at your option)
00032 any later version.
00033 
00034 This library is distributed in the hope that it will be useful,
00035 but WITHOUT ANY WARRANTY; without even the implied warranty of
00036 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00037 GNU General Public License for more details.
00038 
00039 You should have received a copy of the GNU General Public License
00040 along with this library; see the file COPYING.  If not, write to the Free
00041 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00042 
00043 As a special exception, if you link this library with files
00044 compiled with a GNU compiler to produce an executable, this does not cause
00045 the resulting executable to be covered by the GNU General Public License.
00046 This exception does not however invalidate any other reasons why
00047 the executable file might be covered by the GNU General Public License. */
00048 
00049 /* Written by Magnus Fromreide (magfr@lysator.liu.se). */
00050 /* seekoff and ideas for overflow is largely borrowed from libstdc++-v3 */
00051 
00052 #include <iostream.h>
00053 #include <streambuf.h>
00054 #include <string>
00055 
00056 namespace std
00057 {
00058   class stringbuf : public streambuf
00059   {
00060   public:
00061     typedef char    char_type;
00062     typedef int     int_type;
00063     typedef streampos   pos_type;
00064     typedef streamoff   off_type;
00065 
00066     explicit
00067     stringbuf(int which=ios::in|ios::out)
00068       : streambuf(), mode(static_cast<ios::open_mode>(which)),
00069     stream(NULL), stream_len(0)
00070     {
00071       stringbuf_init();
00072     }
00073 
00074     explicit
00075     stringbuf(const string &str, int which=ios::in|ios::out)
00076       : streambuf(), mode(static_cast<ios::open_mode>(which)),
00077     stream(NULL), stream_len(0)
00078     {
00079       if (mode & (ios::in|ios::out))
00080     {
00081       stream_len = str.size();
00082       stream = new char_type[stream_len];
00083       str.copy(stream, stream_len);
00084     }
00085       stringbuf_init();
00086     }
00087 
00088     virtual
00089     ~stringbuf()
00090     {
00091       delete[] stream;
00092     }
00093 
00094     string
00095     str() const
00096     {
00097       if (pbase() != 0)
00098     return string(stream, pptr()-pbase());
00099       else
00100     return string();
00101     }
00102 
00103     void
00104     str(const string& str)
00105     {
00106       delete[] stream;
00107       stream_len = str.size();
00108       stream = new char_type[stream_len];
00109       str.copy(stream, stream_len);
00110       stringbuf_init();
00111     }
00112 
00113   protected:
00114     // The buffer is already in gptr, so if it ends then it is out of data.
00115     virtual int
00116     underflow()
00117     {
00118       return EOF;
00119     }
00120 
00121     virtual int
00122     overflow(int c = EOF)
00123     {
00124       int res;
00125       if (mode & ios::out)
00126     {
00127       if (c != EOF)
00128         {
00129           streamsize old_stream_len = stream_len;
00130           stream_len += 1;
00131           char_type* new_stream = new char_type[stream_len];
00132           memcpy(new_stream, stream, old_stream_len);
00133           delete[] stream;
00134           stream = new_stream;
00135           stringbuf_sync(gptr()-eback(), pptr()-pbase());
00136           sputc(c);
00137           res = c;
00138         }
00139       else
00140         res = EOF;
00141     }
00142       else
00143     res = 0;
00144       return res;
00145     }
00146 
00147     virtual streambuf*
00148     setbuf(char_type* s, streamsize n)
00149     {
00150       if (n != 0)
00151     {
00152       delete[] stream;
00153       stream = new char_type[n];
00154       memcpy(stream, s, n);
00155       stream_len = n;
00156       stringbuf_sync(0, 0);
00157     }
00158       return this;
00159     }
00160 
00161     virtual pos_type
00162     seekoff(off_type off, ios::seek_dir way, int which = ios::in | ios::out)
00163     {
00164       pos_type ret =  pos_type(off_type(-1));
00165       bool testin = which & ios::in && mode & ios::in;
00166       bool testout = which & ios::out && mode & ios::out;
00167       bool testboth = testin && testout && way != ios::cur;
00168 
00169       if (stream_len && ((testin != testout) || testboth))
00170     {
00171       char_type* beg = stream;
00172       char_type* curi = NULL;
00173       char_type* curo = NULL;
00174       char_type* endi = NULL;
00175       char_type* endo = NULL;
00176 
00177       if (testin)
00178         {
00179           curi = gptr();
00180           endi = egptr();
00181         }
00182       if (testout)
00183         {
00184           curo = pptr();
00185           endo = epptr();
00186         }
00187 
00188       off_type newoffi = 0;
00189       off_type newoffo = 0;
00190       if (way == ios::beg)
00191         {
00192           newoffi = beg - curi;
00193           newoffo = beg - curo;
00194         }
00195       else if (way == ios::end)
00196         {
00197           newoffi = endi - curi;
00198           newoffo = endo - curo;
00199         }
00200 
00201       if (testin && newoffi + off + curi - beg >= 0 &&
00202           endi - beg >= newoffi + off + curi - beg)
00203         {
00204           gbump(newoffi + off);
00205           ret = pos_type(newoffi + off + curi);
00206         }
00207       if (testout && newoffo + off + curo - beg >= 0 &&
00208           endo - beg >= newoffo + off + curo - beg)
00209         {
00210           pbump(newoffo + off);
00211           ret = pos_type(newoffo + off + curo);
00212         }
00213     }
00214       return ret;
00215     }
00216 
00217     virtual pos_type
00218     seekpos(pos_type sp, int which = ios::in | ios::out)
00219     {
00220       pos_type ret = seekoff(sp, ios::beg, which);
00221       return ret;
00222     }
00223 
00224   private:
00225     void
00226     stringbuf_sync(streamsize i, streamsize o)
00227     {
00228       if (mode & ios::in)
00229     setg(stream, stream + i, stream + stream_len);
00230       if (mode & ios::out)
00231     {
00232       setp(stream, stream + stream_len);
00233       pbump(o);
00234     }
00235     }
00236     void
00237     stringbuf_init()
00238     {
00239       if (mode & ios::ate)
00240     stringbuf_sync(0, stream_len);
00241       else
00242     stringbuf_sync(0, 0);
00243     }
00244 
00245   private:
00246     ios::open_mode  mode;
00247     char_type*      stream;
00248     streamsize      stream_len;
00249   };
00250 
00251   class istringstream : public istream {
00252   public:
00253     typedef char    char_type;
00254     typedef int     int_type;
00255     typedef streampos   pos_type;
00256     typedef streamoff   off_type;
00257 
00258     explicit
00259     istringstream(int which=ios::in)
00260       : istream(&sb), sb(which | ios::in)
00261     { }
00262 
00263     explicit
00264     istringstream(const string& str, int which=ios::in)
00265       : istream(&sb), sb(str, which | ios::in)
00266     { }
00267 
00268     stringbuf*
00269     rdbuf() const
00270     {
00271       return const_cast<stringbuf*>(&sb);
00272     }
00273 
00274     string
00275     str() const
00276     {
00277       return rdbuf()->str();
00278     }
00279     void
00280     str(const string& s)
00281     {
00282       rdbuf()->str(s);
00283     }
00284   private:
00285     stringbuf sb;
00286   };
00287 
00288   class ostringstream : public ostream {
00289   public:
00290     typedef char    char_type;
00291     typedef int     int_type;
00292     typedef streampos   pos_type;
00293     typedef streamoff   off_type;
00294 
00295     explicit
00296     ostringstream(int which=ios::out)
00297       : ostream(&sb), sb(which | ios::out)
00298     { }
00299 
00300     explicit
00301     ostringstream(const string& str, int which=ios::out)
00302       : ostream(&sb), sb(str, which | ios::out)
00303     { }
00304 
00305     stringbuf*
00306     rdbuf() const
00307     {
00308       return const_cast<stringbuf*>(&sb);
00309     }
00310 
00311     string
00312     str() const
00313     {
00314       return rdbuf()->str();
00315     }
00316 
00317     void str(const string& s)
00318     {
00319       rdbuf()->str(s);
00320     }
00321   private:
00322     stringbuf sb;
00323   };
00324 
00325   class stringstream : public iostream {
00326   public:
00327     typedef char    char_type;
00328     typedef int     int_type;
00329     typedef streampos   pos_type;
00330     typedef streamoff   off_type;
00331 
00332     explicit
00333     stringstream(int which=ios::out|ios::in)
00334       : iostream(&sb), sb(which)
00335     { }
00336 
00337     explicit
00338     stringstream(const string& str, int which=ios::out|ios::in)
00339       : iostream(&sb), sb(str, which)
00340     { }
00341 
00342     stringbuf*
00343     rdbuf() const
00344     {
00345       return const_cast<stringbuf*>(&sb);
00346     }
00347 
00348     string
00349     str() const
00350     {
00351       return rdbuf()->str();
00352     }
00353 
00354     void
00355     str(const string& s)
00356     {
00357       rdbuf()->str(s);
00358     }
00359   private:
00360     stringbuf sb;
00361   };
00362 };
00363 
00364 #else /* not g++ 2.95 and no <sstream> */
00365 
00366 #error "Standard C++ library is missing required sstream header."
00367 
00368 #endif /* not g++ 2.95 and no <sstream> */
00369 
00370 #include "stdpost.h"
00371 #include "stdistream.h"

Generated on Fri Nov 6 00:21:15 2009 for synergy-plus by  doxygen 1.3.9.1