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 #include "FileModes.h"
00026 #include "BinaryFile.h"
00027
00028 #ifdef WIN32
00029 #include <winsock2.h>
00030 #else
00031 #include <netinet/in.h>
00032 #endif
00033
00034 #ifdef _MSC_VER
00035
00036 typedef __int32 int32_t;
00037 typedef unsigned __int32 uint32_t;
00038 typedef __int64 int64_t;
00039 typedef unsigned __int32 uint64_t;
00040 #else
00041 #include <stdint.h>
00042 #endif
00043
00044
00045 using namespace DUtils;
00046
00047 BinaryFile::BinaryFile(void): m_is_little_endian(-1)
00048 {
00049 setEndianness();
00050 }
00051
00052 BinaryFile::~BinaryFile(void)
00053 {
00054 Close();
00055 }
00056
00057 void BinaryFile::Close()
00058 {
00059 if(m_f.is_open()) m_f.close();
00060 }
00061
00062 BinaryFile::BinaryFile(const char *filename, const FILE_MODES mode)
00063 {
00064 Init(filename, mode);
00065 }
00066
00067 BinaryFile::BinaryFile(const string &filename, const FILE_MODES mode)
00068 {
00069 Init(filename.c_str(), mode);
00070 }
00071
00072 void BinaryFile::Init(const char *filename, const FILE_MODES mode)
00073 {
00074 m_is_little_endian = -1;
00075 setEndianness();
00076
00077 if(mode & READ){
00078 OpenForReading(filename);
00079 }else if((mode & WRITE) && (mode & APPEND)){
00080 OpenForAppending(filename);
00081 }else if(mode & WRITE){
00082 OpenForWriting(filename);
00083 }else{
00084 throw DException("Wrong access mode");
00085 }
00086 }
00087
00088 void BinaryFile::OpenForReading(const char *filename)
00089 {
00090 Close();
00091
00092 m_f.open(filename, ios::in | ios::binary);
00093 if(!m_f.is_open()){
00094 throw DException(string("Cannot open ") + filename + " for reading");
00095 }else{
00096 m_mode = READ;
00097 }
00098 }
00099
00100 void BinaryFile::OpenForWriting(const char *filename)
00101 {
00102 Close();
00103
00104 m_f.open(filename, ios::out | ios::binary);
00105 if(!m_f.is_open()){
00106 throw DException(string("Cannot open ") + filename + " for writing");
00107 }else{
00108 m_mode = WRITE;
00109 }
00110 }
00111
00112 void BinaryFile::OpenForAppending(const char *filename)
00113 {
00114 Close();
00115
00116 m_f.open(filename, ios::out | ios::app | ios::binary);
00117 if(!m_f.is_open()){
00118 throw DException(string("Cannot open ") + filename + " for writing at the end");
00119 }else{
00120 m_mode = DUtils::FILE_MODES(WRITE | APPEND);
00121 }
00122 }
00123
00124 void BinaryFile::DiscardBytes(int count)
00125 {
00126 if(!m_f.is_open()) throw DException("File is not open");
00127
00128 if(m_mode & READ){
00129 m_f.ignore(count);
00130 }else
00131 throw DException("Wrong access mode");
00132 }
00133
00134 inline bool BinaryFile::Eof()
00135 {
00136 return(!m_f.is_open() || m_f.eof());
00137 }
00138
00139 unsigned int BinaryFile::BytesRead()
00140 {
00141 if(m_mode & READ){
00142 return (unsigned int)m_f.tellg();
00143 }else
00144 throw DException("Wrong access mode");
00145 }
00146
00147 BinaryFile& BinaryFile::operator<< (char v)
00148 {
00149 if(!m_f.is_open()) throw DException("File is not open");
00150
00151 if(m_mode & WRITE){
00152 m_f.write(&v, 1);
00153 }else
00154 throw DException("Wrong access mode");
00155
00156 return *this;
00157 }
00158
00159 BinaryFile& BinaryFile::operator<< (int v)
00160 {
00161 if(!m_f.is_open()) throw DException("File is not open");
00162
00163 if(m_mode & WRITE){
00164 uint32_t w = htonl(v);
00165 m_f.write((const char *)&w, 4);
00166 }else
00167 throw DException("Wrong access mode");
00168
00169 return *this;
00170 }
00171
00172 BinaryFile& BinaryFile::operator<< (float v)
00173 {
00174 if(!m_f.is_open()) throw DException("File is not open");
00175
00176 if(m_mode & WRITE){
00177 hton_f(v, m_aux);
00178 m_f.write(m_aux, 4);
00179 }else
00180 throw DException("Wrong access mode");
00181
00182 return *this;
00183 }
00184
00185 BinaryFile& BinaryFile::operator<< (double v)
00186 {
00187 if(!m_f.is_open()) throw DException("File is not open");
00188
00189 if(m_mode & WRITE){
00190 hton_d(v, m_aux);
00191 m_f.write(m_aux, 8);
00192 }else
00193 throw DException("Wrong access mode");
00194
00195 return *this;
00196 }
00197
00198 BinaryFile& BinaryFile::operator>>(char &v)
00199 {
00200 if(!m_f.is_open()) throw DException("File is not open");
00201
00202 if(m_mode & READ){
00203 m_f.read(&v, 1);
00204 }else
00205 throw DException("Wrong access mode");
00206
00207 return *this;
00208 }
00209
00210 BinaryFile& BinaryFile::operator>>(int &v)
00211 {
00212 if(!m_f.is_open()) throw DException("File is not open");
00213
00214 if(m_mode & READ){
00215 m_f.read(m_aux, 4);
00216 uint32_t *w = ((uint32_t*)&m_aux[0]);
00217 v = (int)htonl(*w);
00218 }else
00219 throw DException("Wrong access mode");
00220
00221 return *this;
00222 }
00223
00224 BinaryFile& BinaryFile::operator>>(float &v)
00225 {
00226 if(!m_f.is_open()) throw DException("File is not open");
00227
00228 if(m_mode & READ){
00229 m_f.read(m_aux, 4);
00230 v = ntoh_f(m_aux);
00231 }else
00232 throw DException("Wrong access mode");
00233
00234 return *this;
00235 }
00236
00237 BinaryFile& BinaryFile::operator>>(double &v)
00238 {
00239 if(!m_f.is_open()) throw DException("File is not open");
00240
00241 if(m_mode & READ){
00242 m_f.read(m_aux, 8);
00243 v = ntoh_d(m_aux);
00244 }else
00245 throw DException("Wrong access mode");
00246
00247 return *this;
00248 }
00249
00250
00251 void BinaryFile::hton_f(float v, char buf[8]) const
00252 {
00253 unsigned char *w = (unsigned char *)&v;
00254
00255
00256 if(isLittleEndian()){
00257 buf[0] = w[3];
00258 buf[1] = w[2];
00259 buf[2] = w[1];
00260 buf[3] = w[0];
00261 }else{
00262 buf[0] = w[0];
00263 buf[1] = w[1];
00264 buf[2] = w[2];
00265 buf[3] = w[3];
00266 }
00267 }
00268
00269 float BinaryFile::ntoh_f(char buf[8]) const
00270 {
00271 float v;
00272 unsigned char *w = (unsigned char*)&v;
00273
00274
00275 if(isLittleEndian()){
00276 w[3] = buf[0];
00277 w[2] = buf[1];
00278 w[1] = buf[2];
00279 w[0] = buf[3];
00280 }else{
00281 w[0] = buf[0];
00282 w[1] = buf[1];
00283 w[2] = buf[2];
00284 w[3] = buf[3];
00285 }
00286
00287 return v;
00288 }
00289
00290 void BinaryFile::hton_d(double v, char buf[8]) const
00291 {
00292 unsigned char *w = (unsigned char *)&v;
00293
00294
00295 if(isLittleEndian()){
00296 buf[0] = w[7];
00297 buf[1] = w[6];
00298 buf[2] = w[5];
00299 buf[3] = w[4];
00300 buf[4] = w[3];
00301 buf[5] = w[2];
00302 buf[6] = w[1];
00303 buf[7] = w[0];
00304 }else{
00305 buf[0] = w[0];
00306 buf[1] = w[1];
00307 buf[2] = w[2];
00308 buf[3] = w[3];
00309 buf[4] = w[4];
00310 buf[5] = w[5];
00311 buf[6] = w[6];
00312 buf[7] = w[7];
00313 }
00314 }
00315
00316 double BinaryFile::ntoh_d(char buf[8]) const
00317 {
00318 double v;
00319 unsigned char *w = (unsigned char*)&v;
00320
00321
00322 if(isLittleEndian()){
00323 w[7] = buf[0];
00324 w[6] = buf[1];
00325 w[5] = buf[2];
00326 w[4] = buf[3];
00327 w[3] = buf[4];
00328 w[2] = buf[5];
00329 w[1] = buf[6];
00330 w[0] = buf[7];
00331 }else{
00332 w[0] = buf[0];
00333 w[1] = buf[1];
00334 w[2] = buf[2];
00335 w[3] = buf[3];
00336 w[4] = buf[4];
00337 w[5] = buf[5];
00338 w[6] = buf[6];
00339 w[7] = buf[7];
00340 }
00341
00342 return v;
00343 }
00344
00345 void BinaryFile::setEndianness()
00346 {
00347 if(m_is_little_endian == -1){
00348 char SwapTest[2] = { 1, 0 };
00349 short *p = (short *) SwapTest;
00350 m_is_little_endian = (*p == 1 ? 1 : 0);
00351 }
00352 }
00353