00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
#include "Object.h"
00046
#include "stringutils.h"
00047
#include <plearn/io/fileutils.h>
00048
#include "TypeFactory.h"
00049
00050
00051
#include <algorithm>
00052
00053
namespace PLearn {
00054
using namespace std;
00055
00056 Object::Object()
00057 {}
00058
00059 PLEARN_IMPLEMENT_OBJECT(
Object,
"Base class for PLearn Objects",
"NO HELP");
00060
00061
00062
void Object::makeDeepCopyFromShallowCopy(map<const void*, void*>& copies)
00063 {}
00064
00065 void Object::setOption(
const string& optionname,
const string& value)
00066 {
00067 istrstream in_(value.c_str());
00068
PStream in(&in_);
00069
readOptionVal(in, optionname);
00070 }
00071
00072 string Object::getOption(
const string &optionname)
const
00073
{
00074 ostrstream out_;
00075
PStream out(&out_);
00076
writeOptionVal(out, optionname);
00077
char* buf = out_.str();
00078
int n = out_.pcount();
00079
string s(buf,n);
00080 out_.freeze(
false);
00081
return removeblanks(s);
00082 }
00083
00084 void Object::changeOptions(
const map<string,string>& name_value)
00085 {
00086 map<string,string>::const_iterator it = name_value.begin();
00087 map<string,string>::const_iterator itend = name_value.end();
00088
while(it!=itend)
00089 {
00090
setOption(it->first, it->second);
00091 ++it;
00092 }
00093 }
00094
00095 void Object::changeOption(
const string& optionname,
const string& value)
00096 {
00097 map<string,string> name_value;
00098 name_value[optionname] = value;
00099
changeOptions(name_value);
00100 }
00101
00102 void Object::build_()
00103 {}
00104
00105 void Object::build()
00106 {}
00107
00108 string Object::info()
const {
return classname(); }
00109
00110 void Object::print(ostream& out)
const
00111
{
00112
PStream pout(&out);
00113 pout << *
this <<
endl;
00114
00115 }
00116
00117
00118 void Object::readOptionVal(
PStream &in,
const string &optionname)
00119 {
00120
try
00121 {
00122
OptionList &options =
getOptionList();
00123
for (OptionList::iterator it = options.begin(); it != options.end(); ++it)
00124 {
00125
if ((*it)->optionname() == optionname)
00126 {
00127 (*it)->read(
this, in);
00128
return;
00129 }
00130 }
00131
00132
00133
00134 size_t lb_pos = optionname.find(
'[');
00135 size_t rb_pos = optionname.find(
']');
00136 size_t dot_pos = optionname.find(
'.');
00137
if (rb_pos != string::npos)
00138 {
00139
if (lb_pos == string::npos)
00140
PLERROR(
"Object::readOptionVal() - Unmatched brackets");
00141
string optname = optionname.substr(0, lb_pos);
00142
if (dot_pos == string::npos || rb_pos < dot_pos)
00143 {
00144
int i =
toint(optionname.substr(lb_pos + 1, rb_pos - lb_pos - 1));
00145
for (OptionList::iterator it = options.begin(); it != options.end(); ++it)
00146
if ((*it)->optionname() == optname)
00147 {
00148 (*it)->getIndexedObject(
this, i)->readOptionVal(in, optionname.substr(rb_pos + 2));
00149
return;
00150 }
00151 }
00152 }
00153
else if (lb_pos != string::npos)
00154
PLERROR(
"Object::readOptionVal() - Unmatched brackets");
00155
00156
00157
if (dot_pos != string::npos)
00158 {
00159
00160
string optname = optionname.substr(0, dot_pos);
00161
string optoptname = optionname.substr(dot_pos + 1);
00162
for (OptionList::iterator it = options.begin(); it != options.end(); ++it)
00163
if ((*it)->optionname() == optname)
00164 {
00165 (*it)->getAsObject(
this)->readOptionVal(in, optoptname);
00166
return;
00167 }
00168 }
00169 }
00170
catch(
const PLearnError& e)
00171 {
00172
PLERROR(
"Problem while attempting to read value of option %s of a %s:\n %s",
00173 optionname.c_str(),
classname().c_str(), e.message().c_str());
00174 }
00175
00176
00177
PLERROR(
"There is no option named %s in a %s", optionname.c_str(),
classname().c_str());
00178 }
00179
00180
void
00181 Object::writeOptionVal(
PStream &out,
const string &optionname)
const
00182
{
00183
OptionList &options =
getOptionList();
00184
for (OptionList::iterator it = options.begin(); it != options.end(); ++it)
00185
if ((*it)->optionname() == optionname) {
00186 (*it)->write(
this, out);
00187
return;
00188 }
00189
00190
00191
00192 size_t lb_pos = optionname.find(
'[');
00193 size_t rb_pos = optionname.find(
']');
00194 size_t dot_pos = optionname.find(
'.');
00195
if (rb_pos != string::npos) {
00196
if (lb_pos == string::npos)
00197
PLERROR(
"Object::writeOptionVal() - Unmatched brackets");
00198
string optname = optionname.substr(0, lb_pos);
00199
if (dot_pos == string::npos || rb_pos < dot_pos) {
00200
int i =
toint(optionname.substr(lb_pos + 1, rb_pos - lb_pos - 1));
00201
for (OptionList::iterator it = options.begin(); it != options.end(); ++it)
00202
if ((*it)->optionname() == optname) {
00203 (*it)->getIndexedObject(
this, i)->writeOptionVal(out, optionname.substr(rb_pos + 2));
00204
return;
00205 }
00206 }
00207 }
else if (lb_pos != string::npos)
00208
PLERROR(
"Object::writeOptionVal() - Unmatched brackets");
00209
00210
00211
if (dot_pos != string::npos) {
00212
00213
string optname = optionname.substr(0, dot_pos);
00214
string optoptname = optionname.substr(dot_pos + 1);
00215
for (OptionList::iterator it = options.begin(); it != options.end(); ++it)
00216
if ((*it)->optionname() == optname) {
00217 (*it)->getAsObject(
this)->writeOptionVal(out, optoptname);
00218
return;
00219 }
00220 }
00221
00222
PLERROR(
"Object::writeOptionVal() - Unknown option \"%s\"", optionname.c_str());
00223 }
00224
00225
00226 string Object::getOptionsToSave()
const
00227
{
00228
string res =
"";
00229
OptionList& options =
getOptionList();
00230
00231
for( OptionList::iterator it = options.begin(); it!=options.end(); ++it )
00232 {
00233
OptionBase::flag_t flags = (*it)->flags();
00234
if(!(flags & OptionBase::nosave))
00235 res += (*it)->optionname() +
" ";
00236 }
00237
return res;
00238 }
00239
00240
00241 void Object::newread(
PStream &in)
00242 {
00243
string cl;
00244 in.
getline(cl,
'(');
00245 cl =
removeblanks(cl);
00246
if (cl !=
classname())
00247
PLERROR(
"Object::newread() - Was expecting \"%s\", but read \"%s\"",
00248
classname().
c_str(), cl.c_str());
00249
00250 in.
skipBlanksAndComments();
00251
int c = in.
get();
00252
if (c !=
')')
00253 {
00254 in.
unget();
00255
for (;;)
00256 {
00257
00258
string optionname;
00259 in.
getline(optionname,
'=');
00260 optionname =
removeblanks(optionname);
00261 in.
skipBlanksAndComments();
00262
00263
OptionList &options =
getOptionList();
00264 OptionList::iterator it = find_if(options.begin(), options.end(),
00265 bind2nd(mem_fun(&OptionBase::isOptionNamed), optionname));
00266
00267
if (it!=options.end() && (*it)->shouldBeSkipped() )
00268 (*it)->read_and_discard(in);
00269
else
00270
readOptionVal(in, optionname);
00271
00272 in.
skipBlanksAndCommentsAndSeparators();
00273
if (in.
peek() ==
')')
00274 {
00275 in.
get();
00276
break;
00277 }
00278 }
00279 }
00280
build();
00281 }
00282
00283 void Object::newwrite(
PStream &out)
const
00284
{
00285
vector<string> optnames =
split(
getOptionsToSave());
00286 out.
write(
classname());
00287 out.
write(
"(\n");
00288
for (size_t i = 0; i < optnames.size(); ++i)
00289 {
00290 out.
write(optnames[i]);
00291 out.
write(
" = ");
00292
writeOptionVal(out, optnames[i]);
00293
if (i < optnames.size() - 1)
00294 out.
write(
";\n");
00295 }
00296 out.
write(
" )\n");
00297 }
00298
00299
00300 void Object::write(ostream& out_)
const
00301
{
00302
PStream out(&out_);
00303
newwrite(out);
00304 }
00305
00306 void Object::read(istream& in_)
00307 {
00308 in_ >>
ws;
00309
int c = in_.
peek();
00310
if(c==
'<')
00311
oldread(in_);
00312
else {
00313
PStream in(&in_);
00314
newread(in);
00315 }
00316 }
00317
00318
00319 void Object::call(
const string& methodname,
int nargs,
PStream& in_parameters,
PStream& out_results)
00320 {
00321
PLERROR(
"In Object::call no method named %s supported by this object's call method.", methodname.c_str());
00322 }
00323
00324 void Object::run()
00325 {
PLERROR(
"Not a runnable Object"); }
00326
00327 void Object::oldread(istream& in)
00328 {
PLERROR(
"oldread method not implemented for this object"); }
00329
00330 void Object::save(
const string& filename)
const
00331
{
PLearn::save(filename, *
this); }
00332
00333 void Object::load(
const string& filename)
00334 {
PLearn::load(filename, *
this); }
00335
00336 Object::~Object()
00337 {}
00338
00339
00340 Object*
loadObject(
const string &filename)
00341 {
00342 ifstream in_(filename.c_str());
00343
if (!in_)
00344
PLERROR(
"loadObject() - Could not open file \"%s\" for reading", filename.c_str());
00345
00346
PStream in(&in_);
00347
Object *o =
readObject(in);
00348 o->
build();
00349
return o;
00350 }
00351
00352 Object*
macroLoadObject(
const string &filename, map<string, string>& vars)
00353 {
00354
string script =
readFileAndMacroProcess(filename, vars);
00355
PIStringStream sin(script);
00356
Object* o =
readObject(sin);
00357 o->
build();
00358
return o;
00359 }
00360
00361 Object*
macroLoadObject(
const string &filename)
00362 {
00363 map<string, string> vars;
00364
return macroLoadObject(filename,vars);
00365 }
00366
00367 Object*
readObject(
PStream &in,
unsigned int id)
00368 {
00369
Object *o=0;
00370 in.
skipBlanksAndCommentsAndSeparators();
00371
00372
00373
pl_streammarker fence(in.
pl_rdbuf());
00374
00375
int c = in.
peek();
00376
if (c ==
'<')
00377 {
00378 in.
get();
00379
string cl;
00380 in.
getline(cl,
'>');
00381 cl =
removeblanks(cl);
00382
if (cl ==
"null")
00383
return 0;
00384 size_t p = cl.find(
":");
00385
if (p != string::npos)
00386 cl = cl.substr(0, p);
00387 o = TypeFactory::instance().newObject(cl);
00388
if (!o)
00389
PLERROR(
"readObject() - Type \"%s\" not declared in TypeFactory map (did you do a proper DECLARE_NAME_AND_DEEPCOPY?)", cl.c_str());
00390
00391 in.
pl_rdbuf()->
seekmark(fence);
00392 o->
read(in.
_do_not_use_this_method_rawin_());
00393 }
00394
else if (c ==
'*')
00395 {
00396 in >> o;
00397 }
00398
else if(c ==
'`')
00399 {
00400 in.
get();
00401
string fname;
00402 in.
getline(
fname,
'`');
00403
fname =
removeblanks(
fname);
00404
00405
00406
00407 o =
loadObject(
fname);
00408 }
00409
else
00410 {
00411
string cl;
00412 in.
getline(cl,
'(');
00413 cl =
removeblanks(cl);
00414
00415 o = TypeFactory::instance().newObject(cl);
00416
if (!o)
00417
PLERROR(
"readObject() - Type \"%s\" not declared in TypeFactory map (did you do a proper DECLARE_NAME_AND_DEEPCOPY?)", cl.c_str());
00418 in.
pl_rdbuf()->
seekmark(fence);
00419 o->
newread(in);
00420 }
00421
00422
if (
id != UINT_MAX)
00423 in.
copies_map_in[
id] = o;
00424
return o;
00425 }
00426
00427
00428 PStream&
operator>>(
PStream& in,
Object*& x)
00429 {
00430 in.
skipBlanksAndCommentsAndSeparators();
00431
if (in.
peek() ==
'*')
00432 {
00433 in.
get();
00434
unsigned int id;
00435 in >>
id;
00436 in.
skipBlanksAndCommentsAndSeparators();
00437
if (
id==0)
00438
x = 0;
00439
else if (in.
peek() ==
'-')
00440 {
00441 in.
get();
00442
char cc = in.
get();
00443
if(cc !=
'>')
00444
PLERROR(
"In PStream::operator>>(Object*&) Wrong format. Expecting \"*%d->\" but got \"*%d-%c\".",
id,
id, cc);
00445 in.
skipBlanksAndCommentsAndSeparators();
00446
if(
x)
00447 in >> *
x;
00448
else
00449
x =
readObject(in,
id);
00450 in.
skipBlanksAndCommentsAndSeparators();
00451 in.
copies_map_in[
id]=
x;
00452 }
00453
else
00454 {
00455
00456 map<unsigned int, void *>::iterator it = in.
copies_map_in.find(
id);
00457
if (it == in.
copies_map_in.end())
00458
PLERROR(
"In PStream::operator>>(Object*&) object (ptr) to be read has not been previously defined");
00459
x= static_cast<Object *>(it->second);
00460 }
00461 }
00462
else
00463 {
00464
x =
readObject(in);
00465 in.
skipBlanksAndCommentsAndSeparators();
00466 }
00467
00468
return in;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 }
00501
00502
00504
extern "C"
00505 {
00506 void printobj(
PLearn::Object* p)
00507 {
00508
PLearn::PStream perr(&std::cerr);
00509 perr << *p;
00510 perr.
endl();
00511 }
00512 }
00513
00514