00001 #ifndef SCT_FILE_OSTREAMFILE_H
00002 #define SCT_FILE_OSTREAMFILE_H
00003
00004 #include "../OStream.h"
00005 #include "../IoExceptions.h"
00006
00007 #include <cstdio>
00008 #include <string>
00009 #include <cstring>
00010
00011
00012 #ifdef _GNU_SOURCE
00013 #define FWRITE fwrite_unlocked
00014 #define FLOCKFILE(a) flockfile(a)
00015 #define FUNLOCKFILE(a) funlockfile(a)
00016 #else
00017 #define FWRITE fwrite
00018 #define FLOCKFILE(a)
00019 #define FUNLOCKFILE(a)
00020 #endif
00021
00022
00023 using std::fopen;
00024 using std::fclose;
00025 using std::fwrite;
00026 using std::ftell;
00027 using std::strlen;
00028 using std::string;
00029
00030 namespace Sct {
00031 namespace File {
00032
00033 template<typename T>
00034 void write(FILE* f, T t);
00035
00036 template<typename T>
00037 void writeArray(FILE* f, const T* t, size_t size);
00038
00039 class OStreamFile : public virtual OStream {
00040 public:
00041 OStreamFile(const string& fileName) : file(0) {
00042 file = fopen(fileName.c_str(), "wb");
00043 if (!file) {
00044 throw FileException(fileName, "Couldn't open file", __FILE__, __LINE__);
00045 }
00046 setvbuf(file, 0, _IOFBF, BUFSIZ);
00047 FLOCKFILE(file);
00048 }
00049
00050 virtual ~OStreamFile() {
00051 if (file) {
00052 FUNLOCKFILE(file);
00053 fclose(file);
00054 }
00055 }
00056
00057 virtual OStream & operator<<(bool val) {
00058 write(file, val);
00059 return *this;
00060 }
00061
00062 virtual OStream & operator<<(char val) {
00063 write(file, val);
00064 return *this;
00065 }
00066
00067 virtual OStream & operator<<(unsigned char val) {
00068 write(file, val);
00069 return *this;
00070 }
00071
00072 virtual OStream & operator<<(short val) {
00073 write(file, val);
00074 return *this;
00075 }
00076
00077 virtual OStream & operator<<(unsigned short val){
00078 write(file, val);
00079 return *this;
00080 }
00081
00082 virtual OStream & operator<<(int val) {
00083 write(file, val);
00084 return *this;
00085 }
00086
00087 virtual OStream & operator<<(unsigned int val) {
00088 write(file, val);
00089 return *this;
00090 }
00091
00092 virtual OStream & operator<<(long val) {
00093 write(file, val);
00094 return *this;
00095 }
00096
00097 virtual OStream & operator<<(unsigned long val) {
00098 write(file, val);
00099 return *this;
00100 }
00101
00102 virtual OStream & operator<<(double val) {
00103 write(file, val);
00104 return *this;
00105 }
00106
00107 virtual OStream & operator<<(float val) {
00108 write(file, val);
00109 return *this;
00110 }
00111
00112 virtual OStream & operator<<(const std::string & val) {
00113 *this << val.c_str();
00114 return *this;
00115 }
00116
00117
00118
00119
00120 virtual OStream & operator<<(const char * str) {
00121 writeArray(file, str, strlen(str)+1);
00122 return *this;
00123 }
00124
00125 virtual OStream & operator<<(const unsigned char * str) {
00126 writeArray(file, str, strlen((char*)str)+1);
00127 return *this;
00128 }
00129
00130 virtual OStream & put(const bool* p, size_t size) {
00131 writeArray(file, p, size);
00132 return *this;
00133 }
00134
00135 virtual OStream & put(const char* p, size_t size) {
00136 writeArray(file, p, size);
00137 return *this;
00138 }
00139
00140 virtual OStream & put(const unsigned char* p, size_t size) {
00141 writeArray(file, p, size);
00142 return *this;
00143 }
00144
00145 virtual OStream & put(const short* p, size_t size) {
00146 writeArray(file, p, size);
00147 return *this;
00148 }
00149
00150 virtual OStream & put(const unsigned short* p, size_t size) {
00151 writeArray(file, p, size);
00152 return *this;
00153 }
00154
00155 virtual OStream & put(const int* p, size_t size) {
00156 writeArray(file, p, size);
00157 return *this;
00158 }
00159
00160 virtual OStream & put(const unsigned int* p, size_t size) {
00161 writeArray(file, p, size);
00162 return *this;
00163 }
00164
00165 virtual OStream & put(const long* p, size_t size) {
00166 writeArray(file, p, size);
00167 return *this;
00168 }
00169
00170 virtual OStream & put(const unsigned long* p, size_t size) {
00171 writeArray(file, p, size);
00172 return *this;
00173 }
00174
00175 virtual OStream & put(const float* p, size_t size) {
00176 writeArray(file, p, size);
00177 return *this;
00178 }
00179
00180 virtual OStream & put(const double* p, size_t size) {
00181 writeArray(file, p, size);
00182 return *this;
00183 }
00184
00185 virtual OStream & put(const std::string* p, size_t size) {
00186 writeArray(file, p, size);
00187 return *this;
00188 }
00189
00190
00191
00192
00193 private:
00194 FILE* file;
00195 };
00196
00197 template<typename T>
00198 void write(FILE* f, T t) {
00199 FWRITE(&t, sizeof(T), 1, f);
00200 }
00201
00202 template<typename T>
00203 void writeArray(FILE* f, const T* t, size_t size) {
00204
00205 write(f, size);
00206 FWRITE(t, sizeof(T), size, f);
00207 }
00208
00209
00210 }
00211 }
00212
00213 #undef FWRITE
00214 #endif //SCT_FILE_OSTREAMFILE_H