liborigin2 13/09/2010
/builddir/build/BUILD/liborigin2-20101029/endianfstream.hh
Go to the documentation of this file.
00001 /***************************************************************************
00002     File                 : endianfstream.hh
00003     --------------------------------------------------------------------
00004     Copyright            : (C) 2008 Alex Kargovsky
00005                            Email (use @ for *)  : kargovsky*yumr.phys.msu.su
00006     Description          : Endianless file stream class
00007 
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *                                                                         *
00012  *  This program is free software; you can redistribute it and/or modify   *
00013  *  it under the terms of the GNU General Public License as published by   *
00014  *  the Free Software Foundation; either version 2 of the License, or      *
00015  *  (at your option) any later version.                                    *
00016  *                                                                         *
00017  *  This program is distributed in the hope that it will be useful,        *
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
00020  *  GNU General Public License for more details.                           *
00021  *                                                                         *
00022  *   You should have received a copy of the GNU General Public License     *
00023  *   along with this program; if not, write to the Free Software           *
00024  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
00025  *   Boston, MA  02110-1301  USA                                           *
00026  *                                                                         *
00027  ***************************************************************************/
00028 
00029 #ifndef ENDIAN_FSTREAM_H
00030 #define ENDIAN_FSTREAM_H
00031 
00032 #include <fstream>
00033 #include "OriginObj.h"
00034 
00035 namespace std
00036 {
00037     class iendianfstream : public ifstream
00038     {
00039     public:
00040         iendianfstream(const char *_Filename, ios_base::openmode _Mode = ios_base::in)
00041             :   ifstream(_Filename, _Mode)
00042         {
00043             short word = 0x4321;
00044             bigEndian = (*(char*)& word) != 0x21;
00045         };
00046 
00047         iendianfstream& operator>>(bool& value)
00048         {
00049             char c;
00050             get(c);
00051             value = (c != 0);
00052             return *this;
00053         }
00054 
00055         iendianfstream& operator>>(char& value)
00056         {
00057             get(value);
00058             return *this;
00059         }
00060 
00061         iendianfstream& operator>>(unsigned char& value)
00062         {
00063             get(reinterpret_cast<char&>(value));
00064             return *this;
00065         }
00066 
00067         iendianfstream& operator>>(short& value)
00068         {
00069             read(reinterpret_cast<char*>(&value), sizeof(value));
00070             if(bigEndian)
00071                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00072 
00073             return *this;
00074         }
00075 
00076         iendianfstream& operator>>(unsigned short& value)
00077         {
00078             read(reinterpret_cast<char*>(&value), sizeof(value));
00079             if(bigEndian)
00080                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00081 
00082             return *this;
00083         }
00084 
00085         iendianfstream& operator>>(int& value)
00086         {
00087             read(reinterpret_cast<char*>(&value), sizeof(value));
00088             if(bigEndian)
00089                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00090 
00091             return *this;
00092         }
00093 
00094         iendianfstream& operator>>(unsigned int& value)
00095         {
00096             read(reinterpret_cast<char*>(&value), sizeof(value));
00097             if(bigEndian)
00098                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00099 
00100             return *this;
00101         }
00102 
00103         iendianfstream& operator>>(long& value)
00104         {
00105             read(reinterpret_cast<char*>(&value), sizeof(value));
00106             if(bigEndian)
00107                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00108 
00109             return *this;
00110         }
00111 
00112         iendianfstream& operator>>(unsigned long& value)
00113         {
00114             read(reinterpret_cast<char*>(&value), sizeof(value));
00115             if(bigEndian)
00116                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00117 
00118             return *this;
00119         }
00120 
00121         iendianfstream& operator>>(float& value)
00122         {
00123             read(reinterpret_cast<char*>(&value), sizeof(value));
00124             if(bigEndian)
00125                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00126 
00127             return *this;
00128         }
00129 
00130         iendianfstream& operator>>(double& value)
00131         {
00132             read(reinterpret_cast<char*>(&value), sizeof(value));
00133             if(bigEndian)
00134                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00135 
00136             return *this;
00137         }
00138 
00139         iendianfstream& operator>>(long double& value)
00140         {
00141             read(reinterpret_cast<char*>(&value), sizeof(value));
00142             if(bigEndian)
00143                 swap_bytes(reinterpret_cast<unsigned char*>(&value), sizeof(value));
00144 
00145             return *this;
00146         }
00147 
00148         iendianfstream& operator>>(string& value)
00149         {
00150             read(reinterpret_cast<char*>(&value[0]), value.size());
00151             string::size_type pos = value.find_first_of('\0');
00152             if(pos != string::npos)
00153                 value.resize(pos);
00154 
00155             return *this;
00156         }
00157 
00158         iendianfstream& operator>>(Origin::Color& value)
00159         {
00160             unsigned char color[4];
00161             read(reinterpret_cast<char*>(&color), sizeof(color));
00162             switch(color[3])
00163             {
00164             case 0:
00165                 if(color[0] < 0x64)
00166                 {
00167                     value.type = Origin::Color::Regular;
00168                     value.regular = color[0];
00169                 }
00170                 else
00171                 {
00172                     switch(color[2])
00173                     {
00174                     case 0:
00175                         value.type = Origin::Color::Indexing;
00176                         break;
00177                     case 0x40:
00178                         value.type = Origin::Color::Mapping;
00179                         break;
00180                     case 0x80:
00181                         value.type = Origin::Color::RGB;
00182                         break;
00183                     }
00184 
00185                     value.column = color[0] - 0x64;
00186                 }
00187                 
00188                 break;
00189             case 1:
00190                 value.type = Origin::Color::Custom;
00191                 for(int i = 0; i < 3; ++i)
00192                     value.custom[i] = color[i];
00193                 break;
00194             case 0x20:
00195                 value.type = Origin::Color::Increment;
00196                 value.starting = color[1];
00197                 break;
00198             case 0xFF:
00199                 if(color[0] == 0xFC)
00200                     value.type = Origin::Color::None;
00201                 else if(color[0] == 0xF7)
00202                     value.type = Origin::Color::Automatic;
00203 
00204                 break;
00205 
00206             default:
00207                 value.type = Origin::Color::Regular;
00208                 value.regular = color[0];
00209                 break;
00210 
00211             }
00212 
00213             return *this;
00214         }
00215 
00216     private:
00217         bool bigEndian;
00218         void swap_bytes(unsigned char* data, int size)
00219         {
00220             register int i = 0;
00221             register int j = size - 1;
00222             while(i < j)
00223             {
00224                 std::swap(data[i], data[j]);
00225                 ++i, --j;
00226             }
00227         }
00228     };
00229 }
00230 
00231 #endif // ENDIAN_FSTREAM_H