liborigin2 13/09/2010
|
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