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
00207 return *this;
00208 }
00209
00210 private:
00211 bool bigEndian;
00212 void swap_bytes(unsigned char* data, int size)
00213 {
00214 register int i = 0;
00215 register int j = size - 1;
00216 while(i < j)
00217 {
00218 std::swap(data[i], data[j]);
00219 ++i, --j;
00220 }
00221 }
00222 };
00223 }
00224
00225 #endif // ENDIAN_FSTREAM_H