File indexing completed on 2025-02-16 09:49:48
0001 /* 0002 File : endianfstream.hh 0003 Description : Endianless file stream class 0004 -------------------------------------------------------------------- 0005 SPDX-FileCopyrightText: 2008 Alex Kargovsky <kargovsky@yumr.phys.msu.su> 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef ENDIAN_FSTREAM_H 0010 #define ENDIAN_FSTREAM_H 0011 0012 #include "OriginObj.h" 0013 0014 #include <fstream> 0015 0016 namespace endianfstream { 0017 class ORIGIN_EXPORT iendianfstream : public std::ifstream 0018 { 0019 public: 0020 iendianfstream(const char *_Filename, std::ios_base::openmode _Mode = std::ios_base::in) 0021 : std::ifstream(_Filename, _Mode) 0022 { 0023 short word = 0x4321; 0024 bigEndian = (*(char *)&word) != 0x21; 0025 }; 0026 0027 iendianfstream &operator>>(bool &value) 0028 { 0029 char c; 0030 get(c); 0031 value = (c != 0); 0032 return *this; 0033 } 0034 0035 iendianfstream &operator>>(char &value) 0036 { 0037 get(value); 0038 return *this; 0039 } 0040 0041 iendianfstream &operator>>(unsigned char &value) 0042 { 0043 get(reinterpret_cast<char &>(value)); 0044 return *this; 0045 } 0046 0047 iendianfstream &operator>>(short &value) 0048 { 0049 read(reinterpret_cast<char *>(&value), sizeof(value)); 0050 if (bigEndian) 0051 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0052 0053 return *this; 0054 } 0055 0056 iendianfstream &operator>>(unsigned short &value) 0057 { 0058 read(reinterpret_cast<char *>(&value), sizeof(value)); 0059 if (bigEndian) 0060 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0061 0062 return *this; 0063 } 0064 0065 iendianfstream &operator>>(int &value) 0066 { 0067 read(reinterpret_cast<char *>(&value), sizeof(value)); 0068 if (bigEndian) 0069 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0070 0071 return *this; 0072 } 0073 0074 iendianfstream &operator>>(unsigned int &value) 0075 { 0076 read(reinterpret_cast<char *>(&value), sizeof(value)); 0077 if (bigEndian) 0078 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0079 0080 return *this; 0081 } 0082 0083 iendianfstream &operator>>(long &value) 0084 { 0085 read(reinterpret_cast<char *>(&value), sizeof(value)); 0086 if (bigEndian) 0087 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0088 0089 return *this; 0090 } 0091 0092 iendianfstream &operator>>(unsigned long &value) 0093 { 0094 read(reinterpret_cast<char *>(&value), sizeof(value)); 0095 if (bigEndian) 0096 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0097 0098 return *this; 0099 } 0100 0101 iendianfstream &operator>>(float &value) 0102 { 0103 read(reinterpret_cast<char *>(&value), sizeof(value)); 0104 if (bigEndian) 0105 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0106 0107 return *this; 0108 } 0109 0110 iendianfstream &operator>>(double &value) 0111 { 0112 read(reinterpret_cast<char *>(&value), sizeof(value)); 0113 if (bigEndian) 0114 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0115 0116 return *this; 0117 } 0118 0119 iendianfstream &operator>>(long double &value) 0120 { 0121 read(reinterpret_cast<char *>(&value), sizeof(value)); 0122 if (bigEndian) 0123 swap_bytes(reinterpret_cast<unsigned char *>(&value), sizeof(value)); 0124 0125 return *this; 0126 } 0127 0128 iendianfstream &operator>>(std::string &value) 0129 { 0130 read(reinterpret_cast<char *>(&value[0]), value.size()); 0131 std::string::size_type pos = value.find_first_of('\0'); 0132 if (pos != std::string::npos) 0133 value.resize(pos); 0134 0135 return *this; 0136 } 0137 0138 iendianfstream &operator>>(Origin::Color &value) 0139 { 0140 unsigned char color[4]; 0141 read(reinterpret_cast<char *>(&color), sizeof(color)); 0142 switch (color[3]) { 0143 case 0: 0144 if (color[0] < 0x64) { 0145 value.type = Origin::Color::Regular; 0146 value.regular = color[0]; 0147 } else { 0148 switch (color[2]) { 0149 case 0: 0150 value.type = Origin::Color::Indexing; 0151 break; 0152 case 0x40: 0153 value.type = Origin::Color::Mapping; 0154 break; 0155 case 0x80: 0156 value.type = Origin::Color::RGB; 0157 break; 0158 } 0159 0160 value.column = color[0] - 0x64; 0161 } 0162 0163 break; 0164 case 1: 0165 value.type = Origin::Color::Custom; 0166 for (int i = 0; i < 3; ++i) 0167 value.custom[i] = color[i]; 0168 break; 0169 case 0x20: 0170 value.type = Origin::Color::Increment; 0171 value.starting = color[1]; 0172 break; 0173 case 0xFF: 0174 if (color[0] == 0xFC) 0175 value.type = Origin::Color::None; 0176 else if (color[0] == 0xF7) 0177 value.type = Origin::Color::Automatic; 0178 0179 break; 0180 0181 default: 0182 value.type = Origin::Color::Regular; 0183 value.regular = color[0]; 0184 break; 0185 } 0186 0187 return *this; 0188 } 0189 0190 private: 0191 bool bigEndian; 0192 void swap_bytes(unsigned char *data, int size) 0193 { 0194 int i = 0; 0195 int j = size - 1; 0196 while (i < j) { 0197 std::swap(data[i], data[j]); 0198 ++i, --j; 0199 } 0200 } 0201 }; 0202 } 0203 0204 #endif // ENDIAN_FSTREAM_H