00001 #ifndef SCT_FILE_ISTREAMFILE_H
00002 #define SCT_FILE_ISTREAMFILE_H
00003
00004 #include "../IStream.h"
00005 #include "../IoExceptions.h"
00006
00007 #include <cstdio>
00008 #include <string>
00009 #include <cstring>
00010 #include <stdio_ext.h>
00011
00012 #ifdef _GNU_SOURCE
00013 #define FREAD fread_unlocked
00014 #define FLOCKFILE(a) flockfile(a)
00015 #define FUNLOCKFILE(a) funlockfile(a)
00016 #else
00017 #define FREAD fread
00018 #define FLOCKFILE(a)
00019 #define FUNLOCKFILE(a)
00020 #endif
00021
00022 using std::fopen;
00023 using std::fclose;
00024 using std::fread;
00025 using std::ftell;
00026 using std::string;
00027 using std::strcpy;
00028 using std::cout;
00029 using std::endl;
00030
00031 namespace Sct {
00032 namespace File {
00033
00034 template<typename T>
00035 void readArray(FILE* file, T* p, size_t size, size_t actualSize);
00036
00037 template<typename T>
00038 void readArrayCreate(FILE* file, T** p, size_t& size);
00039
00040 template<typename T>
00041 void readArrayNoCreate(FILE* file, T* p, size_t size);
00042
00043 template<typename T>
00044 void read(FILE* f, T& p);
00045
00046 class IStreamFile : public virtual IStream {
00047 public:
00048 IStreamFile(const string& fileName) : file(0) {
00049 file = fopen(fileName.c_str(), "rb");
00050 if (!file) {
00051 throw FileException(fileName, "Couldn't open file", __FILE__, __LINE__);
00052 }
00053
00054 setvbuf(file, 0, _IOFBF, BUFSIZ);
00055 FLOCKFILE(file);
00056 }
00057
00058 virtual ~IStreamFile() {
00059 if (file) {
00060 FUNLOCKFILE(file);
00061 fclose(file);
00062 }
00063 }
00064
00065 virtual IStream & operator>>(char *str) {
00066 readArrayNoCreate(file, str, ULONG_MAX);
00067 return *this;
00068 }
00069
00070 virtual IStream & operator>>(unsigned char *str) {
00071 readArrayNoCreate(file, str, ULONG_MAX);
00072 return *this;
00073 }
00074
00075 virtual IStream & operator>>(char **str) {
00076 size_t size;
00077 readArrayCreate(file, str, size);
00078 return *this;
00079 }
00080
00081 virtual IStream & operator>>(unsigned char **str) {
00082 size_t size;
00083 readArrayCreate(file, str, size);
00084 return *this;
00085 }
00086
00087 virtual IStream & operator>>(bool& val) {
00088 read(file, val);
00089 return *this;
00090 }
00091
00092 virtual IStream & operator>>(char& val) {
00093 read(file, val);
00094 return *this;
00095 }
00096
00097 virtual IStream & operator>>(unsigned char& val) {
00098 read(file, val);
00099 return *this;
00100 }
00101
00102 virtual IStream & operator>>(short& val) {
00103 read(file, val);
00104 return *this;
00105 }
00106
00107 virtual IStream & operator>>(unsigned short& val) {
00108 read(file, val);
00109 return *this;
00110 }
00111
00112 virtual IStream & operator>>(int& val) {
00113 read(file, val);
00114 return *this;
00115 }
00116
00117 virtual IStream & operator>>(unsigned int& val) {
00118 read(file, val);
00119 return *this;
00120 }
00121
00122 virtual IStream & operator>>(long& val) {
00123 read(file, val);
00124 return *this;
00125 }
00126
00127 virtual IStream & operator>>(unsigned long& val) {
00128 read(file, val);
00129 return *this;
00130 }
00131
00132 virtual IStream & operator>>(float& val) {
00133 read(file, val);
00134 return *this;
00135 }
00136
00137 virtual IStream & operator>>(double& val) {
00138 read(file, val);
00139 return *this;
00140 }
00141
00142 virtual IStream & operator>>(std::string& val) {
00143 char* buffer;
00144 *this >> &buffer;
00145 val = buffer;
00146 return *this;
00147 }
00148
00149
00150
00151
00152
00153 virtual IStream & get ( bool ** p, size_t & size ) {
00154 readArrayCreate(file, p, size);
00155 return *this;
00156 }
00157
00158 virtual IStream & get ( char ** p, size_t & size ) {
00159 readArrayCreate(file, p, size);
00160 return *this;
00161 }
00162
00163 virtual IStream & get ( unsigned char ** p, size_t & size ) {
00164 readArrayCreate(file, p, size);
00165 return *this;
00166 }
00167
00168 virtual IStream & get( short ** p, size_t & size ) {
00169 readArrayCreate(file, p, size);
00170 return *this;
00171 }
00172
00173 virtual IStream & get( unsigned short ** p, size_t & size ) {
00174 readArrayCreate(file, p, size);
00175 return *this;
00176 }
00177
00178 virtual IStream & get( int ** p, size_t & size ) {
00179 readArrayCreate(file, p, size);
00180 return *this;
00181 }
00182
00183 virtual IStream & get( unsigned int ** p, size_t & size ) {
00184 readArrayCreate(file, p, size);
00185 return *this;
00186 }
00187
00188 virtual IStream & get( long ** p, size_t & size ) {
00189 readArrayCreate(file, p, size);
00190 return *this;
00191 }
00192
00193 virtual IStream & get( unsigned long ** p, size_t & size ) {
00194 readArrayCreate(file, p, size);
00195 return *this;
00196 }
00197
00198 virtual IStream & get( float ** p, size_t & size ) {
00199 readArrayCreate(file, p, size);
00200 return *this;
00201 }
00202
00203 virtual IStream & get( double ** p, size_t & size ) {
00204 readArrayCreate(file, p, size);
00205 return *this;
00206 }
00207
00208 virtual IStream & get( std::string ** p, size_t & size ) {
00209 readArrayCreate(file, p, size);
00210 return *this;
00211 }
00212
00213
00214
00215
00216 virtual IStream & get( bool * const p, const size_t size ) {
00217 readArrayNoCreate(file, p, size);
00218 return *this;
00219 }
00220
00221 virtual IStream & get( char * const p, const size_t size ) {
00222 readArrayNoCreate(file, p, size);
00223 return *this;
00224 }
00225
00226 virtual IStream & get( unsigned char * const p, const size_t size ) {
00227 readArrayNoCreate(file, p, size);
00228 return *this;
00229 }
00230
00231 virtual IStream & get( short * const p, const size_t size ) {
00232 readArrayNoCreate(file, p, size);
00233 return *this;
00234 }
00235
00236 virtual IStream & get( unsigned short * const p, const size_t size ) {
00237 readArrayNoCreate(file, p, size);
00238 return *this;
00239 }
00240
00241 virtual IStream & get( int * const p, const size_t size ) {
00242 readArrayNoCreate(file, p, size);
00243 return *this;
00244 }
00245
00246 virtual IStream & get( unsigned int * const p, const size_t size ) {
00247 readArrayNoCreate(file, p, size);
00248 return *this;
00249 }
00250
00251 virtual IStream & get( long * const p, const size_t size ) {
00252 readArrayNoCreate(file, p, size);
00253 return *this;
00254 }
00255
00256 virtual IStream & get( unsigned long * const p, const size_t size ) {
00257 readArrayNoCreate(file, p, size);
00258 return *this;
00259 }
00260
00261 virtual IStream & get( float * const p, const size_t size ) {
00262 readArrayNoCreate(file, p, size);
00263 return *this;
00264 }
00265
00266 virtual IStream & get( double * const p, const size_t size ) {
00267 readArrayNoCreate(file, p, size);
00268 return *this;
00269 }
00270
00271 virtual IStream & get( std::string * const p, const size_t size ) {
00272 readArrayNoCreate(file, p, size);
00273 return *this;
00274 }
00275
00276
00277
00278
00279 private:
00280 FILE* file;
00281 };
00282
00283 template<typename T>
00284 void readArray(FILE* file, T* p, size_t size, size_t actualSize) {
00285 if (size >= actualSize) {
00286 FREAD(p, sizeof(T), actualSize, file);
00287 return;
00288 } else {
00289 cout << "Reading less than stored array size - buffer size: " << size << " actual size: " << actualSize << " at: " << ftell(file) << endl;
00290 FREAD(p, sizeof(T), size, file);
00291 T temp[actualSize-size];
00292 FREAD(&temp, sizeof(T), actualSize-size, file);
00293 }
00294 }
00295
00296 template<typename T>
00297 void readArrayCreate(FILE* file, T** p, size_t& size) {
00298
00299 read(file, size);
00300
00301 *p = new T[size];
00302 readArray(file, *p, size, size);
00303 }
00304
00305 template<typename T>
00306 void readArrayNoCreate(FILE* file, T* p, size_t size) {
00307
00308 size_t actualSize = 0;
00309 read(file, actualSize);
00310
00311 readArray(file, p, size, actualSize);
00312 }
00313
00314 template<typename T>
00315 void read(FILE* f, T& p) {
00316 FREAD(&p, sizeof(T), 1, f);
00317 }
00318
00319 }
00320 }
00321
00322 #undef FREAD
00323
00324 #endif //SCT_FILE_ISTREAMFILE_H