00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _MX_ETERN_H_
00018 #define _MX_ETERN_H_
00019
00020 #include<map>
00021 #include<string>
00022 #include<fstream>
00023 #include<iostream>
00024
00025
00026 namespace mx
00027 {
00028
00029 using std::map;
00030 using std::fstream;
00031
00032
00033 template<typename Type> int defaultRead(fstream &fobj, Type &typeobject)
00034 {
00035 fobj.read((char*)&typeobject, sizeof(typeobject));
00036 return 0;
00037 }
00038
00039 template<typename Type> int defaultWrite(fstream &fobj, Type &typeobject)
00040 {
00041 fobj.write((char*)&typeobject, sizeof(typeobject));
00042 return 0;
00043 }
00044
00045
00046
00047
00048
00049
00050 template<typename T>
00051 class mxEternal;
00052
00053
00054 template<typename Type>
00056 class mxEternalRW {
00057 public:
00058
00064 mxEternalRW(int (*rf)(fstream &fobj, Type &typeobject) = defaultRead, int (*wf)(fstream &fobj, Type &typeobject) = defaultWrite)
00065 {
00066 readFunction = rf;
00067 writeFunction = wf;
00068 }
00069 virtual ~mxEternalRW() { }
00070 private:
00071 Type typedata;
00072 int readType(fstream &fobj);
00073 int writeType(fstream &fobj);
00074
00075 int (*readFunction)(fstream &fobj, Type &typeobject);
00076 int (*writeFunction)(fstream &fobj, Type &typeobject);
00077
00078 friend class mxEternal<Type>;
00079 };
00080
00081
00082 template<typename Type>
00084 class mxEternal {
00085 public:
00090 mxEternal(std::string name="etern.mxdb", mxEternalRW<Type> *typeobj = new mxEternalRW<Type>);
00091 virtual ~mxEternal();
00092
00096 void setStreamRW(mxEternalRW<Type> *typeobjx);
00100 int read();
00104 int save();
00105
00109 const std::string getName() const { return name; }
00110
00111
00112
00117 Type &operator[](std::string n) { return this_map[n]; }
00118
00123 map<std::string, Type> *operator->() { return &this_map; }
00124
00126 typedef typename std::map<std::string, Type>::iterator iterator;
00127
00128 private:
00129
00130
00131 std::string name;
00132 std::fstream fobj,fobj_write;
00133 Type typedata;
00134
00135 mxEternalRW<Type> *typeobj;
00136 std::map<std::string, Type> this_map;
00137
00139 int readType();
00141 int writeType();
00142
00143 mxEternal(mxEternal<Type> &t);
00144 mxEternal<Type>& operator=(const mxEternal<Type> &type);
00145 };
00146
00147
00148 template<typename Type> std::ostream& operator<<(std::ostream &out, mxEternal<Type> &type);
00149
00150
00151
00152
00153
00154
00155
00156
00157 template<typename Type>
00158 int mxEternalRW<Type>::readType(fstream &fobj)
00159 {
00160
00161
00162 readFunction(fobj, typedata);
00163 return 0;
00164 }
00165
00166 template<typename Type>
00167 int mxEternalRW<Type>::writeType(fstream &fobj)
00168 {
00169
00170 writeFunction(fobj, typedata);
00171 return 0;
00172 }
00173
00174 template<typename Type> mxEternal<Type>::mxEternal(std::string vname, mxEternalRW<Type> *typeobject)
00175 {
00176 typeobj = typeobject;
00177 name = vname;
00178 read();
00179 }
00180
00181 template<typename Type> void mxEternal<Type>::setStreamRW(mxEternalRW<Type> *typeobjx)
00182 {
00183 if(typeobj != 0) delete typeobj;
00184 typeobj = 0;
00185 typeobj = typeobjx;
00186 }
00187
00188 template<typename Type> mxEternal<Type>::~mxEternal()
00189 {
00190 save();
00191 if(this->typeobj != 0) delete typeobj;
00192 this_map.erase(this_map.begin(), this_map.end());
00193 }
00194
00195 template<typename Type> int mxEternal<Type>:: read()
00196 {
00197
00198 if(!this_map.empty()) this_map.erase(this_map.begin(), this_map.end());
00199
00200 fobj.open(name.c_str(), std::ios::in | std::ios::binary);
00201 if(!fobj.is_open()) return 1;
00202
00203 unsigned int number_of_types = 0;
00204
00205 fobj.read((char*)&number_of_types, sizeof(number_of_types));
00206
00207 for(unsigned int i = 0; (i < number_of_types) && (!fobj.eof()); i++)
00208 {
00209 unsigned int name_index = 0;
00210 fobj.read((char*)&name_index, sizeof(name_index));
00211
00212 if(static_cast<int>(name_index) < 0) return -1;
00213
00214 char *buf = 0;
00215
00216 try
00217 {
00218
00219 buf = new char [ name_index+1 ];
00220 fobj.read((char*)buf, name_index);
00221 buf[name_index] = 0;
00222 readType();
00223 this_map[buf] = typedata;
00224 delete [] buf;
00225 buf = 0;
00226
00227 }
00228 catch (...)
00229 {
00230
00231 if(buf != 0) delete [] buf;
00232
00233 }
00234
00235 }
00236 fobj.close();
00237 return 0;
00238 }
00239 template<typename Type> int mxEternal<Type>::save()
00240 {
00241
00242 fobj_write.open(name.c_str(), std::ios::out | std::ios::binary);
00243 if(!fobj_write.is_open()) return -1;
00244
00245 unsigned int length = this_map.size();
00246
00247 fobj_write.write((char*)&length, sizeof(length));
00248
00249 typename mxEternal<Type>::iterator i;
00250
00251 for(i= this_map.begin(); i!=this_map.end(); i++)
00252 {
00253
00254 unsigned int len =i->first.length();
00255 const char *str = i->first.c_str();
00256 fobj_write.write((char*)&len, sizeof(len));
00257 fobj_write.write((char*)str,len);
00258 typedata = i->second;
00259 writeType();
00260 }
00261
00262 fobj_write.close();
00263 return 0;
00264
00265 }
00266
00267
00268
00269 template<typename Type> int mxEternal<Type>::readType()
00270 {
00271 typeobj->readType(fobj);
00272 typedata = typeobj->typedata;
00273 return 0;
00274 }
00275
00276 template<typename Type> int mxEternal<Type>::writeType()
00277 {
00278 typeobj->typedata = typedata;
00279 typeobj->writeType(fobj_write);
00280 return 0;
00281 }
00282
00283
00284
00285 template<typename Type> std::ostream& operator<<(std::ostream &out, mxEternal<Type> &type)
00286 {
00287
00288
00289 typename mxEternal<Type>::iterator i;
00290 int counter = 0;
00291 out << " eternal map (" << type.getName() << ") = { \n";
00292
00293 for(i = type->begin(); i != type->end(); counter++)
00294 {
00295 out << "[" << "\"" << i->first << "\"" << " : ";
00296 out << (i->second);
00297 out << " ] ";
00298 i++;
00299 if(i != type->end()) out << ",\n";
00300 }
00301 out << "\n}\n";
00302 return out;
00303 }
00304
00305 }
00306 #endif
00307
00308
00309