Stream.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <QBuffer>
00028 # include <QByteArray>
00029 # include <QDataStream>
00030 # include <QIODevice>
00031 # include <cstdlib>
00032 # include <string>
00033 # include <cstdio>
00034 # include <cstring>
00035 #ifdef __GNUC__
00036 # include <stdint.h>
00037 #endif
00038 #endif
00039 
00040 #include "Stream.h"
00041 #include "Swap.h"
00042 #include "FileInfo.h"
00043 
00044 using namespace Base;
00045 
00046 Stream::Stream() : _swap(false)
00047 {
00048 }
00049 
00050 Stream::~Stream()
00051 {
00052 }
00053 
00054 Stream::ByteOrder Stream::byteOrder() const
00055 {
00056     return _swap ? BigEndian : LittleEndian;
00057 }
00058 
00059 void Stream::setByteOrder(ByteOrder bo)
00060 {
00061     _swap = (bo == BigEndian);
00062 }
00063 
00064 OutputStream::OutputStream(std::ostream &rout) : _out(rout)
00065 {
00066 }
00067 
00068 OutputStream::~OutputStream()
00069 {
00070 }
00071 
00072 OutputStream& OutputStream::operator << (bool b)
00073 {
00074     _out.write((const char*)&b, sizeof(bool));
00075     return *this;
00076 }
00077 
00078 OutputStream& OutputStream::operator << (int8_t ch)
00079 {
00080     _out.write((const char*)&ch, sizeof(int8_t));
00081     return *this;
00082 }
00083 
00084 OutputStream& OutputStream::operator << (uint8_t uch)
00085 {
00086     _out.write((const char*)&uch, sizeof(uint8_t));
00087     return *this;
00088 }
00089 
00090 OutputStream& OutputStream::operator << (int16_t s)
00091 {
00092     if (_swap) SwapEndian<int16_t>(s);
00093     _out.write((const char*)&s, sizeof(int16_t));
00094     return *this;
00095 }
00096 
00097 OutputStream& OutputStream::operator << (uint16_t us)
00098 {
00099     if (_swap) SwapEndian<uint16_t>(us);
00100     _out.write((const char*)&us, sizeof(uint16_t));
00101     return *this;
00102 }
00103 
00104 OutputStream& OutputStream::operator << (int32_t i)
00105 {
00106     if (_swap) SwapEndian<int32_t>(i);
00107     _out.write((const char*)&i, sizeof(int32_t));
00108     return *this;
00109 }
00110 
00111 OutputStream& OutputStream::operator << (uint32_t ui)
00112 {
00113     if (_swap) SwapEndian<uint32_t>(ui);
00114     _out.write((const char*)&ui, sizeof(uint32_t));
00115     return *this;
00116 }
00117 
00118 OutputStream& OutputStream::operator << (int64_t l)
00119 {
00120     if (_swap) SwapEndian<int64_t>(l);
00121     _out.write((const char*)&l, sizeof(int64_t));
00122     return *this;
00123 }
00124 
00125 OutputStream& OutputStream::operator << (uint64_t ul)
00126 {
00127     if (_swap) SwapEndian<uint64_t>(ul);
00128     _out.write((const char*)&ul, sizeof(uint64_t));
00129     return *this;
00130 }
00131 
00132 OutputStream& OutputStream::operator << (float f)
00133 {
00134     if (_swap) SwapEndian<float>(f);
00135     _out.write((const char*)&f, sizeof(float));
00136     return *this;
00137 }
00138 
00139 OutputStream& OutputStream::operator << (double d)
00140 {
00141     if (_swap) SwapEndian<double>(d);
00142     _out.write((const char*)&d, sizeof(double));
00143     return *this;
00144 }
00145 
00146 InputStream::InputStream(std::istream &rin) : _in(rin)
00147 {
00148 }
00149 
00150 InputStream::~InputStream()
00151 {
00152 }
00153 
00154 InputStream& InputStream::operator >> (bool& b)
00155 {
00156     _in.read((char*)&b, sizeof(bool));
00157     return *this;
00158 }
00159 
00160 InputStream& InputStream::operator >> (int8_t& ch)
00161 {
00162     _in.read((char*)&ch, sizeof(int8_t));
00163     return *this;
00164 }
00165 
00166 InputStream& InputStream::operator >> (uint8_t& uch)
00167 {
00168     _in.read((char*)&uch, sizeof(uint8_t));
00169     return *this;
00170 }
00171 
00172 InputStream& InputStream::operator >> (int16_t& s)
00173 {
00174     _in.read((char*)&s, sizeof(int16_t));
00175     if (_swap) SwapEndian<int16_t>(s);
00176     return *this;
00177 }
00178 
00179 InputStream& InputStream::operator >> (uint16_t& us)
00180 {
00181     _in.read((char*)&us, sizeof(uint16_t));
00182     if (_swap) SwapEndian<uint16_t>(us);
00183     return *this;
00184 }
00185 
00186 InputStream& InputStream::operator >> (int32_t& i)
00187 {
00188     _in.read((char*)&i, sizeof(int32_t));
00189     if (_swap) SwapEndian<int32_t>(i);
00190     return *this;
00191 }
00192 
00193 InputStream& InputStream::operator >> (uint32_t& ui)
00194 {
00195     _in.read((char*)&ui, sizeof(uint32_t));
00196     if (_swap) SwapEndian<uint32_t>(ui);
00197     return *this;
00198 }
00199 
00200 InputStream& InputStream::operator >> (int64_t& l)
00201 {
00202     _in.read((char*)&l, sizeof(int64_t));
00203     if (_swap) SwapEndian<int64_t>(l);
00204     return *this;
00205 }
00206 
00207 InputStream& InputStream::operator >> (uint64_t& ul)
00208 {
00209     _in.read((char*)&ul, sizeof(uint64_t));
00210     if (_swap) SwapEndian<uint64_t>(ul);
00211     return *this;
00212 }
00213 
00214 InputStream& InputStream::operator >> (float& f)
00215 {
00216     _in.read((char*)&f, sizeof(float));
00217     if (_swap) SwapEndian<float>(f);
00218     return *this;
00219 }
00220 
00221 InputStream& InputStream::operator >> (double& d)
00222 {
00223     _in.read((char*)&d, sizeof(double));
00224     if (_swap) SwapEndian<double>(d);
00225     return *this;
00226 }
00227 
00228 // ----------------------------------------------------------------------
00229 
00230 ByteArrayOStreambuf::ByteArrayOStreambuf(QByteArray& ba) : _buffer(new QBuffer(&ba))
00231 {
00232     _buffer->open(QIODevice::WriteOnly);
00233 }
00234 
00235 ByteArrayOStreambuf::~ByteArrayOStreambuf()
00236 {
00237     _buffer->close();
00238     delete _buffer;
00239 }
00240 
00241 std::streambuf::int_type
00242 ByteArrayOStreambuf::overflow(std::streambuf::int_type c)
00243 {
00244     if (c != EOF) {
00245         char z = c;
00246         if (_buffer->write (&z, 1) != 1) {
00247             return EOF;
00248         }
00249     }
00250     return c;
00251 }
00252 
00253 std::streamsize ByteArrayOStreambuf::xsputn (const char* s, std::streamsize num)
00254 {
00255     return _buffer->write(s,num);
00256 }
00257 
00258 std::streambuf::pos_type
00259 ByteArrayOStreambuf::seekoff(std::streambuf::off_type off,
00260                              std::ios_base::seekdir way,
00261                              std::ios_base::openmode /*mode*/)
00262 {
00263     off_type begpos = 0;
00264     off_type endpos = 0;
00265     off_type curpos = _buffer->pos();
00266     switch (way) {
00267         case std::ios_base::beg:
00268             begpos = 0;
00269             endpos = off;
00270             break;
00271         case std::ios_base::cur:
00272             begpos = curpos;
00273             endpos = begpos + off;
00274             break;
00275         case std::ios_base::end:
00276             begpos = _buffer->size();
00277             endpos = begpos;
00278             break;
00279         default:
00280             return pos_type(off_type(-1));
00281     }
00282 
00283     if (endpos != curpos) {
00284         if (!_buffer->seek(endpos))
00285             endpos = -1;
00286     }
00287 
00288     return pos_type(endpos);
00289 }
00290 
00291 std::streambuf::pos_type
00292 ByteArrayOStreambuf::seekpos(std::streambuf::pos_type pos,
00293                              std::ios_base::openmode /*mode*/)
00294 {
00295     return seekoff(pos, std::ios_base::beg);
00296 }
00297 
00298 // ----------------------------------------------------------------------
00299 
00300 ByteArrayIStreambuf::ByteArrayIStreambuf(const QByteArray& data) : _buffer(data)
00301 {
00302     _beg = 0;
00303     _end = data.size();
00304     _cur = 0;
00305 }
00306 
00307 ByteArrayIStreambuf::~ByteArrayIStreambuf()
00308 {
00309 }
00310 
00311 ByteArrayIStreambuf::int_type ByteArrayIStreambuf::underflow()
00312 {
00313     if (_cur == _end)
00314         return traits_type::eof();
00315 
00316     return static_cast<ByteArrayIStreambuf::int_type>(_buffer[_cur]) & 0x000000ff;
00317 }
00318 
00319 ByteArrayIStreambuf::int_type ByteArrayIStreambuf::uflow()
00320 {
00321     if (_cur == _end)
00322         return traits_type::eof();
00323 
00324     return static_cast<ByteArrayIStreambuf::int_type>(_buffer[_cur++]) & 0x000000ff;
00325 }
00326 
00327 ByteArrayIStreambuf::int_type ByteArrayIStreambuf::pbackfail(int_type ch)
00328 {
00329     if (_cur == _beg || (ch != traits_type::eof() && ch != _buffer[_cur-1]))
00330         return traits_type::eof();
00331 
00332     return static_cast<ByteArrayIStreambuf::int_type>(_buffer[--_cur]) & 0x000000ff;
00333 }
00334 
00335 std::streamsize ByteArrayIStreambuf::showmanyc()
00336 {
00337     return _end - _cur;
00338 }
00339 
00340 std::streambuf::pos_type
00341 ByteArrayIStreambuf::seekoff(std::streambuf::off_type off,
00342                              std::ios_base::seekdir way,
00343                              std::ios_base::openmode /*mode*/ )
00344 {
00345     int p_pos=-1;
00346     if (way == std::ios_base::beg)
00347         p_pos = _beg;
00348     else if (way == std::ios_base::end)
00349         p_pos = _end;
00350     else if (way == std::ios_base::cur)
00351         p_pos = _cur;
00352 
00353     if (p_pos > _end)
00354         return traits_type::eof();
00355 
00356     if (((p_pos + off) > _end) || ((p_pos + off) < _beg))
00357         return traits_type::eof();
00358 
00359     _cur = p_pos+ off;
00360 
00361     return ((p_pos+off) - _beg);
00362 }
00363 
00364 std::streambuf::pos_type
00365 ByteArrayIStreambuf::seekpos(std::streambuf::pos_type pos,
00366                              std::ios_base::openmode /*mode*/)
00367 {
00368     return seekoff(pos, std::ios_base::beg);
00369 }
00370 
00371 // ----------------------------------------------------------------------
00372 
00373 IODeviceOStreambuf::IODeviceOStreambuf(QIODevice* dev) : device(dev)
00374 {
00375 }
00376 
00377 IODeviceOStreambuf::~IODeviceOStreambuf()
00378 {
00379 }
00380 
00381 std::streambuf::int_type
00382 IODeviceOStreambuf::overflow(std::streambuf::int_type c)
00383 {
00384     if (c != EOF) {
00385         char z = c;
00386         if (device->write (&z, 1) != 1) {
00387             return EOF;
00388         }
00389     }
00390     return c;
00391 }
00392 
00393 std::streamsize IODeviceOStreambuf::xsputn (const char* s, std::streamsize num)
00394 {
00395     return device->write(s,num);
00396 }
00397 
00398 std::streambuf::pos_type
00399 IODeviceOStreambuf::seekoff(std::streambuf::off_type off,
00400                             std::ios_base::seekdir way,
00401                             std::ios_base::openmode /*mode*/)
00402 {
00403     off_type begpos = 0;
00404     off_type endpos = 0;
00405     off_type curpos = device->pos();
00406     switch (way) {
00407         case std::ios_base::beg:
00408             begpos = 0;
00409             endpos = off;
00410             break;
00411         case std::ios_base::cur:
00412             begpos = curpos;
00413             endpos = begpos + off;
00414             break;
00415         case std::ios_base::end:
00416             begpos = device->size();
00417             endpos = begpos;
00418             break;
00419         default:
00420             return pos_type(off_type(-1));
00421     }
00422 
00423     if (endpos != curpos) {
00424         if (!device->seek(endpos))
00425             endpos = -1;
00426     }
00427 
00428     return pos_type(endpos);
00429 }
00430 
00431 std::streambuf::pos_type
00432 IODeviceOStreambuf::seekpos(std::streambuf::pos_type pos,
00433                             std::ios_base::openmode /*mode*/)
00434 {
00435     return seekoff(pos, std::ios_base::beg);
00436 }
00437 
00438 // ----------------------------------------------------------------------
00439 
00440 IODeviceIStreambuf::IODeviceIStreambuf(QIODevice* dev) : device(dev)
00441 {
00442     setg (buffer+pbSize,     // beginning of putback area
00443           buffer+pbSize,     // read position
00444           buffer+pbSize);    // end position
00445 }
00446 
00447 IODeviceIStreambuf::~IODeviceIStreambuf()
00448 {
00449 }
00450 
00451 std::streambuf::int_type
00452 IODeviceIStreambuf::underflow()
00453 {
00454 #ifndef _MSC_VER
00455 using std::memcpy;
00456 #endif
00457 
00458     // is read position before end of buffer?
00459     if (gptr() < egptr()) {
00460         return *gptr();
00461     }
00462 
00463     /* process size of putback area
00464      * - use number of characters read
00465      * - but at most size of putback area
00466      */
00467     int numPutback;
00468     numPutback = gptr() - eback();
00469     if (numPutback > pbSize) {
00470         numPutback = pbSize;
00471     }
00472 
00473     /* copy up to pbSize characters previously read into
00474      * the putback area
00475      */
00476     memcpy (buffer+(pbSize-numPutback), gptr()-numPutback,
00477             numPutback);
00478 
00479     // read at most bufSize new characters
00480     int num;
00481     num = device->read(buffer+pbSize, bufSize);
00482     if (num <= 0) {
00483         // ERROR or EOF
00484         return EOF;
00485     }
00486 
00487     // reset buffer pointers
00488     setg (buffer+(pbSize-numPutback),   // beginning of putback area
00489           buffer+pbSize,                // read position
00490           buffer+pbSize+num);           // end of buffer
00491 
00492     // return next character
00493     return *gptr();
00494 }
00495 
00496 std::streambuf::pos_type
00497 IODeviceIStreambuf::seekoff(std::streambuf::off_type off,
00498                             std::ios_base::seekdir way,
00499                             std::ios_base::openmode /*mode*/)
00500 {
00501     off_type begpos = 0;
00502     off_type endpos = 0;
00503     off_type curpos = device->pos();
00504     switch (way) {
00505         case std::ios_base::beg:
00506             begpos = 0;
00507             endpos = off;
00508             break;
00509         case std::ios_base::cur:
00510             begpos = curpos;
00511             endpos = begpos + off;
00512             break;
00513         case std::ios_base::end:
00514             begpos = device->size();
00515             endpos = begpos;
00516             break;
00517         default:
00518             return pos_type(off_type(-1));
00519     }
00520 
00521     if (endpos != curpos) {
00522         if (!device->seek(endpos))
00523             endpos = -1;
00524     }
00525 
00526     return pos_type(endpos);
00527 }
00528 
00529 std::streambuf::pos_type
00530 IODeviceIStreambuf::seekpos(std::streambuf::pos_type pos,
00531                             std::ios_base::openmode /*mode*/)
00532 {
00533     return seekoff(pos, std::ios_base::beg);
00534 }
00535 
00536 // ---------------------------------------------------------
00537 
00538 Streambuf::Streambuf(const std::string& data)
00539 {
00540     _beg = data.begin();
00541     _end = data.end();
00542     _cur = _beg;
00543 }
00544 
00545 Streambuf::~Streambuf()
00546 {
00547 }
00548 
00549 Streambuf::int_type Streambuf::underflow()
00550 {
00551     if (_cur == _end)
00552         return traits_type::eof();
00553 
00554     return static_cast<Streambuf::int_type>(*_cur) & 0x000000ff;
00555 }
00556 
00557 Streambuf::int_type Streambuf::uflow()
00558 {
00559     if (_cur == _end)
00560         return traits_type::eof();
00561 
00562     return static_cast<Streambuf::int_type>(*_cur++) & 0x000000ff;
00563 }
00564 
00565 Streambuf::int_type Streambuf::pbackfail( int_type ch )
00566 {
00567     if (_cur == _beg || (ch != traits_type::eof() && ch != _cur[-1]))
00568         return traits_type::eof();
00569 
00570     return static_cast<Streambuf::int_type>(*--_cur) & 0x000000ff;
00571 }
00572 
00573 std::streamsize Streambuf::showmanyc()
00574 {
00575     return _end - _cur;
00576 }
00577 
00578 std::streambuf::pos_type
00579 Streambuf::seekoff(std::streambuf::off_type off,
00580                    std::ios_base::seekdir way,
00581                    std::ios_base::openmode /*mode*/ )
00582 {
00583     std::string::const_iterator p_pos;
00584     if (way == std::ios_base::beg)
00585         p_pos = _beg;
00586     else if (way == std::ios_base::end)
00587         p_pos = _end;
00588     else if (way == std::ios_base::cur)
00589         p_pos = _cur;
00590 
00591     if (p_pos > _end)
00592         return traits_type::eof();
00593 
00594     if (((p_pos + off) > _end) || ((p_pos + off) < _beg))
00595         return traits_type::eof();
00596 
00597     _cur = p_pos+ off;
00598 
00599     return ((p_pos+off) - _beg);
00600 }
00601 
00602 std::streambuf::pos_type
00603 Streambuf::seekpos(std::streambuf::pos_type pos,
00604                    std::ios_base::openmode which/*mode*/)
00605 {
00606     return seekoff(pos, std::ios_base::beg);
00607 }
00608 
00609 // ---------------------------------------------------------
00610 
00611 Base::ofstream::ofstream(const FileInfo& fi, ios_base::openmode mode)
00612 #ifdef _MSC_VER
00613 : std::ofstream(fi.toStdWString().c_str(), mode)
00614 #else
00615 : std::ofstream(fi.filePath().c_str(), mode)
00616 #endif
00617 {
00618 }
00619 
00620 Base::ofstream::~ofstream()
00621 {
00622 }
00623 
00624 Base::ifstream::ifstream(const FileInfo& fi, ios_base::openmode mode)
00625 #ifdef _MSC_VER
00626 : std::ifstream(fi.toStdWString().c_str(), mode)
00627 #else
00628 : std::ifstream(fi.filePath().c_str(), mode)
00629 #endif
00630 {
00631 }
00632 
00633 Base::ifstream::~ifstream()
00634 {
00635 }
00636 

Generated on Wed Nov 23 19:00:41 2011 for FreeCAD by  doxygen 1.6.1