00001 #include "std/config.H"
00002 #include "data_item.H"
00003 #include "mlib/points.H"
00004 #include "ctype.h"
00005
00006 using mlib::Wpt;
00007 using mlib::Wvec;
00008
00009 HASH *DATA_ITEM::_hash = 0;
00010 DATA_ITEM* (*DATA_ITEM::_decode_unknown)(STDdstream&, Cstr_ptr&, DATA_ITEM*) = 0;
00011
00012 const str_ptr NAME_INT ("int");
00013 const str_ptr NAME_DOUBLE ("double");
00014 const str_ptr NAME_VEC3D ("vec3d");
00015 const str_ptr NAME_COLOR ("color");
00016 const str_ptr NAME_POINT3D("point3d");
00017 const str_ptr NAME_STR_PTR("str_ptr");
00018
00019 static int im=DATA_ITEM::add_decoder(NAME(0), new TDI<int>(0), 1);
00020 static int dm=DATA_ITEM::add_decoder(NAME(0.0), new TDI<double>(0), 1);
00021 static int vm=DATA_ITEM::add_decoder(NAME(Wvec()),new TDI<Wvec>(Wvec(0,1,0)), 1);
00022 static int pm=DATA_ITEM::add_decoder(NAME(Wpt()), new TDI<Wpt>(Wpt()), 1);
00023 static int sm=DATA_ITEM::add_decoder(NAME(str_ptr()),new TDI<str_ptr>(str_ptr()), 1);
00024
00025
00026
00027
00028
00029
00030 STAT_STR_RET
00031 DATA_ITEM::static_name()
00032 {
00033 RET_STAT_STR("DATA_ITEM");
00034 }
00035
00036 DATA_ITEM::~DATA_ITEM()
00037 {
00038 }
00039
00040 int
00041 DATA_ITEM::add_decoder(
00042 Cstr_ptr &name,
00043 DATA_ITEM *di,
00044 int copy
00045 )
00046 {
00047 if (!_hash)
00048 _hash = new HASH(128);
00049 _hash->add(**name, (void *) di);
00050 if (copy != -1)
00051 di->_copy = copy;
00052 return 1;
00053 }
00054
00055
00056 DATA_ITEM *
00057 DATA_ITEM::Decode(
00058 STDdstream &d,
00059 int DelayDecoding
00060 )
00061 {
00062
00063 str_ptr str;
00064 d >> str;
00065
00066 if (Config::get_var_bool("DEBUG_DATA_ITEM",false))
00067 cerr << "Decoding: " << str << endl;
00068
00069 DATA_ITEM* di = lookup(str);
00070 if (di) {
00071 if (di->class_name() != str) {
00072
00073
00074
00075 di = _decode_unknown(d, str, di);
00076 if (!di) {
00077 cerr << "DATA_ITEM::Decode - failure, class '"
00078 << di->class_name() << "' can't read '" << str << "'\n";
00079 }
00080 } else {
00081 if (di->_copy)
00082 di = di->dup();
00083 if (!DelayDecoding)
00084 di->decode(d);
00085 }
00086 } else if (str) {
00087 if (_decode_unknown)
00088 di = _decode_unknown(d, str, 0);
00089
00090 if (!di) {
00091 char *x = **str; char _buf[128], *buf = _buf;
00092 while (*x && isupper(*x))
00093 *buf++ = *x++;
00094 *buf++ = '\0';
00095
00096 cerr << "DATA_ITEM::Decode - unknown object " << str <<endl;
00097
00098 }
00099 }
00100
00101 return di;
00102 }
00103
00104 class COMMENT : public TAG {
00105 public:
00106 COMMENT(Cstr_ptr &name = str_ptr("//")) : _name(name) {}
00107 virtual ~COMMENT() {}
00108
00109 STDdstream &format(CDATA_ITEM *, STDdstream &d) { return d; }
00110 STDdstream &decode(CDATA_ITEM *, STDdstream &d) {
00111 _delim.set_stream(&d);
00112 _delim.read_id();
00113 if (d.ascii()) {
00114 const int size = 1024;
00115 char name[size];
00116 d.istr()->getline(name, 1024);
00117 } else {
00118 str_ptr str;
00119 d >> str;
00120 }
00121 return d;
00122 }
00123 virtual Cstr_ptr &name() const { return _name; }
00124 protected:
00125 Cstr_ptr _name;
00126 TAGformat _delim;
00127 };
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 STDdstream &
00145 DATA_ITEM::decode(STDdstream &ds)
00146 {
00147 TAGformat d(&ds, class_name(), 1);
00148 static COMMENT comment;
00149
00150 d.read_id();
00151
00152 if (tags().num() == 1 && tags()[0]->name() == "")
00153 tags()[0]->decode(this, *d);
00154 else
00155 while (d) {
00156 str_ptr tag_name;
00157 *d >> tag_name;
00158 int j;
00159 for (j = 0; j < tags().num(); j++)
00160 if (tags()[j]->name() == tag_name) {
00161 tags()[j]->decode(this, *d);
00162 break;
00163 }
00164 if (j == tags().num()) {
00165 if (comment.name() == tag_name) {
00166 comment.decode(this, *d);
00167 } else {
00168 int count = 0, finished = 0;
00169 while (!finished) {
00170 str_ptr s;
00171 *d >> s;
00172 if (!count && s[0] != '{')
00173 break;
00174
00175 for (int x=0; x < (int)s->len(); x++) {
00176 if (s[x] == '{') count++;
00177 if (s[x] == '}') { count--; if (count == 0) finished=1; }
00178 }
00179 }
00180 cerr << "DATA_ITEM::decode - unrecognized tag '" << tag_name
00181 << "' while decoding class " << class_name() << endl;
00182 }
00183 }
00184 }
00185
00186 d.read_end_id();
00187
00188 recompute();
00189
00190 return *d;
00191 }
00192
00193 STDdstream &
00194 DATA_ITEM::format(STDdstream &ds) const
00195 {
00196 TAGformat d(&ds, class_name(), 1);
00197
00198 if (Config::get_var_bool("DEBUG_DATA_ITEM",false))
00199 cerr << "Formatting " << class_name() << endl;
00200
00201 d.id();
00202 for (int i=0; i<tags().num(); i++)
00203 tags()[i]->format(this, *d);
00204 ds.write_newline();
00205 d.end_id();
00206
00207 return *d;
00208 }