Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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