00001 #ifndef JOT_DATA_ITEM_H_IS_INCLUDED
00002 #define JOT_DATA_ITEM_H_IS_INCLUDED
00003
00004 #include "std/hash.H"
00005 #include "net/stream.H"
00006 #include "net/net_types.H"
00007
00008 #include "rtti.H"
00009
00010 #define DECODER_ADD(X) DATA_ITEM::add_decoder(X::static_name(), new X(), 1)
00011
00012 #define DECLARE_NETWORK_TAGS(CLASS_NAME) \
00013 TAGlist *CLASS_NAME::_##CLASS_NAME##tags = 0; \
00014 static int CLASS_NAME##st=DECODER_ADD(CLASS_NAME);
00015
00016 class COLOR;
00017 class mlib::Wvec;
00018 class mlib::Wpt;
00019 extern Cstr_ptr NAME_INT;
00020 extern Cstr_ptr NAME_DOUBLE;
00021 extern Cstr_ptr NAME_COLOR;
00022 extern Cstr_ptr NAME_VEC3D;
00023 extern Cstr_ptr NAME_POINT3D;
00024 extern Cstr_ptr NAME_STR_PTR;
00025 inline STAT_STR_RET NAME(const str_ptr &) { return NAME_STR_PTR;}
00026 inline STAT_STR_RET NAME(const int &) { return NAME_INT; }
00027 inline STAT_STR_RET NAME(const double &) { return NAME_DOUBLE; }
00028 inline STAT_STR_RET NAME(const mlib::Wvec &) { return NAME_VEC3D; }
00029 inline STAT_STR_RET NAME(const mlib::Wpt &) { return NAME_POINT3D;}
00030 inline STAT_STR_RET NAME(const COLOR &) { return NAME_COLOR;}
00031 template <class T>
00032 inline STAT_STR_RET NAME(const T &x) { return x.class_name(); }
00033
00034 #define CDATA_ITEM const DATA_ITEM
00035 class DATA_ITEM;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 class TAGformat {
00046 protected :
00047 str_ptr _name;
00048 int _multi;
00049 STDdstream *_ds;
00050 public:
00051 TAGformat(STDdstream *d, Cstr_ptr &n,int m):_name(n),_multi(m),_ds(d){}
00052 TAGformat( Cstr_ptr &n,int m):_name(n),_multi(m),_ds(0){}
00053 TAGformat() : _multi(0), _ds(0) {}
00054 void set_stream(STDdstream *d) { _ds = d; }
00055 STDdstream &operator*() { return *_ds; }
00056 STDdstream &read_id() { if (_name != NULL_STR && _multi)
00057 _ds->read_open_delim();
00058 return *_ds; }
00059 STDdstream &read_end_id() { if (_name != NULL_STR && _multi)
00060 _ds->read_close_delim();
00061 return *_ds; }
00062 STDdstream &id() { _ds->write_newline();
00063 if (_name != NULL_STR) {
00064 *_ds << _name; _ds->ws("\t");
00065 if (_multi)
00066 _ds->write_open_delim();
00067 }
00068 return *_ds; }
00069 STDdstream &end_id() { if (_name != NULL_STR && _multi)
00070 _ds->write_close_delim();
00071 return *_ds; }
00072 operator int() { return !_ds->eof()&&_ds->check(); }
00073 Cstr_ptr &name() const { return _name; }
00074 };
00075
00076
00077
00078
00079
00080
00081 class TAG {
00082 public:
00083 TAG() { }
00084 virtual ~TAG() {}
00085 virtual STDdstream &format(CDATA_ITEM *me, STDdstream &d) = 0;
00086 virtual STDdstream &decode(CDATA_ITEM *me, STDdstream &d) = 0;
00087 virtual Cstr_ptr &name() const = 0;
00088 };
00089 typedef ARRAY<TAG *> TAGlist;
00090 #define CTAGlist const TAGlist
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 template <class T>
00104 class TAG_meth : public TAG {
00105 typedef void (T::*infunc )(TAGformat &d);
00106 typedef void (T::*outfunc)(TAGformat &d) const;
00107 TAGformat _delim;
00108 outfunc _format;
00109 infunc _decode;
00110 public:
00111 TAG_meth() { }
00112 TAG_meth(Cstr_ptr &field_name, outfunc format, infunc decode, int multi=0):
00113 _delim(field_name, multi),
00114 _format(format), _decode(decode) { }
00115 virtual ~TAG_meth() {}
00116
00117 STDdstream &format(CDATA_ITEM *me, STDdstream &d) { _delim.set_stream(&d);
00118 (((T *)me)->*_format)(_delim); return d;}
00119 STDdstream &decode(CDATA_ITEM *me, STDdstream &d)
00120 { _delim.set_stream(&d);
00121 _delim.read_id();
00122 (((T *)me)->*_decode)(_delim);
00123 _delim.read_end_id();
00124 return d; }
00125 Cstr_ptr &name() const { return _delim.name(); }
00126 };
00127
00128 template <class T, class V>
00129 class TAG_val : public TAG {
00130 typedef V &(T::*value)();
00131 typedef bool (T::*testval)() const;
00132 TAGformat _delim;
00133 value _value;
00134 testval _test;
00135 public:
00136 TAG_val() { }
00137 TAG_val(Cstr_ptr &field_name, value val, testval test=0)
00138 : _delim(field_name, 0), _value(val), _test(test) { }
00139 virtual ~TAG_val() {}
00140 STDdstream &format(CDATA_ITEM *me, STDdstream &d) {
00141 bool output;
00142
00143 if (_test == 0) output = true;
00144 else {
00145 output = (((T *)me)->*_test)();
00146 }
00147 if (output) {
00148 _delim.set_stream(&d);
00149 _delim.id() << (((T *)me)->*_value)();
00150 }
00151 return d;
00152 }
00153 STDdstream &decode(CDATA_ITEM *me, STDdstream &d)
00154 { _delim.set_stream(&d);
00155 _delim.read_id()>>(((T *)me)->*_value)();
00156 return d; }
00157 Cstr_ptr &name() const { return _delim.name(); }
00158 };
00159
00160 #if WIN32_VCPLUSPLUS_DIDNT_HAVE_PROBLEMS
00161
00162
00163
00164 template <class T, class V>
00165 TAG *TAGval(char *str, V &(T::*value)()) { return new TAG_val<T,V>(str, value);}
00166
00167
00168 template <class T>
00169 TAG *TAGmeth(char *str,
00170 void (T::*ofunc)(TAGformat &) const,
00171 void (T::*ifunc)(TAGformat &),
00172 int multi)
00173 { return new TAG_meth<T>(str, ofunc, ifunc, multi); }
00174 #endif
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 class DATA_ITEM {
00193 private:
00194 static HASH *_hash;
00195 static DATA_ITEM *(*_decode_unknown)(STDdstream &, Cstr_ptr &, DATA_ITEM *);
00196 protected:
00197 int _copy;
00198 TAGlist _DEFINERtags;
00199
00200 public:
00201 DATA_ITEM(int copy = 0) :_copy(copy) {}
00202 virtual ~DATA_ITEM();
00203
00204 virtual CTAGlist &tags() const { return _DEFINERtags; }
00205 virtual void add_tags() const { }
00206 virtual STDdstream &format(STDdstream &d) const;
00207 virtual STDdstream &decode(STDdstream &d);
00208 virtual void recompute() { }
00209
00210
00211 virtual STAT_STR_RET class_name () const = 0;
00212 virtual DATA_ITEM *dup () const = 0;
00213 static STAT_STR_RET static_name();
00214 virtual int is_of_type(Cstr_ptr &t)const { return IS(t); }
00215
00216
00217 static int add_decoder(Cstr_ptr &d, DATA_ITEM *di, int copy= -1);
00218 static void set_default_decoder(DATA_ITEM *(*d)(STDdstream&, Cstr_ptr&,
00219 DATA_ITEM *))
00220 { _decode_unknown = d; }
00221 static DATA_ITEM *Decode (STDdstream &d, int DelayDecoding = 0);
00222 static DATA_ITEM *lookup (Cstr_ptr &d) { return !_hash ? 0 :
00223 (DATA_ITEM *) _hash->find(**d);}
00224
00225 static HASH *di_hash () { return _hash; }
00226 };
00227
00228 inline STDdstream &operator<<(STDdstream &s, CDATA_ITEM &d)
00229 { return d.format(s); }
00230 inline STDdstream &operator>>(STDdstream &s, DATA_ITEM *&d)
00231 { d = d->Decode(s); return s; }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 template <class T>
00242 class TDI : public DATA_ITEM {
00243 protected:
00244 T _x;
00245 TAGlist _tags;
00246 void put_val(TAGformat &d) const { d.id() << _x; d.end_id(); }
00247 void get_val(TAGformat &d) { *d >> _x; }
00248 public:
00249 TDI(const T &x): _x(x)
00250 { _tags+=new TAG_meth<TDI<T> >(NULL_STR, &TDI<T>::put_val, &TDI<T>::get_val, 1);}
00251 T &get() { return _x; }
00252 const T &get() const { return _x; }
00253 virtual DATA_ITEM *dup() const { return new TDI<T>(_x); }
00254 virtual CTAGlist &tags() const { return _tags; }
00255 virtual STAT_STR_RET class_name() const { return NAME(_x); }
00256 };
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 class FUNC_ITEM : public DATA_ITEM {
00267 public:
00268 FUNC_ITEM(Cstr_ptr &n): _name(n) {
00269 if (!lookup(n))
00270 add_decoder(n,this);
00271 _tags += new TAG_meth<FUNC_ITEM>(
00272 str_ptr(), &FUNC_ITEM::put, &FUNC_ITEM::get, 1
00273 );
00274 }
00275
00276 CTAGlist& tags() const { return _tags; }
00277 virtual void put(TAGformat &) const = 0;
00278 virtual void get(TAGformat &) = 0;
00279 virtual DATA_ITEM* dup() const { return (DATA_ITEM *) this;}
00280 virtual STAT_STR_RET class_name() const { return _name; }
00281
00282 protected:
00283 str_ptr _name;
00284 TAGlist _tags;
00285 };
00286
00287 #endif // JOT_DATA_ITEM_H_IS_INCLUDED
00288
00289
00290