📄 statein.cc
字号:
StateIn::get(int*&s){ int r=0; int size; r += get(size); if (size) { s = new int[size]; r += get_array_int(s,size); } else { s = 0; } return r;}intStateIn::get(float*&s){ int r=0; int size; r += get(size); if (size) { s = new float[size]; r += get_array_float(s,size); } else { s = 0; } return r;}intStateIn::get(double*&s){ int r=0; int size; r += get(size); if (size) { s = new double[size]; r += get_array_double(s,size); } else { s = 0; } return r;}intStateIn::version(const ClassDesc* cd){ int classid = classidmap_[(ClassDesc*)cd]; return classdatamap_[classid].version;}intStateIn::get(const ClassDesc**cd){ int r=0; // if a list of class descriptors exist then read it in if (!use_directory()) { int size; r += get(size); while (size) { char* name = new char[size+1]; r += get_array_char(name,size); name[size] = '\0'; int version; r += get(version); ClassDesc* tmp = ClassDesc::name_to_class_desc(name); // save the class descriptor and the version int classid = nextclassid_++; classidmap_[tmp] = classid; StateClassData classdat(version,tmp,name); classdatamap_[classid] = classdat; r += get(size); } } // get the class id for the object int classid; r += get(classid); if (classdatamap_.find(classid) == classdatamap_.end()) { ExEnv::errn() << "ERROR: StateIn: couldn't find class descriptor for classid " << classid << endl; abort(); } // convert the class id into the class descriptor *cd = classdatamap_[classid].classdesc; return r;}voidStateIn::list_objects(ostream &o){ if (SCFormIO::getverbose(o)) { int ii = 1; for (std::map<int,StateInData>::iterator i=ps_.begin(); i!=ps_.end(); i++,ii++) { const StateInData &num(i->second); const char *classname = classdatamap_[num.type].name; o << indent << "object " << ii << " at offset " << num.offset << " is of type " << classname << endl; } } else { int ntot = 0; for (std::map<int,StateClassData>::iterator i=classdatamap_.begin(); i!=classdatamap_.end(); i++) { StateClassData &dat = i->second; if (dat.ninstance > 0) { o << indent << dat.ninstance << " " << dat.name << endl; ntot += dat.ninstance; } } o << indent << "total of " << ntot << endl; }}intStateIn::dir_getobject(Ref<SavableState> &p, const char *name){ int r=0; p = 0; if (!has_directory()) { ExEnv::errn() << "ERROR: StateIn: no directory to get object from" << endl; abort(); } if (!seekable()) { ExEnv::errn() << "ERROR: StateIn: cannot get object because cannot seek" << endl; abort(); } // find the class name and/or object number const char *colon = ::strrchr(name,':'); int number = 1; char *classname = 0; if (colon == 0) { if (isdigit(*name)) number = atoi(name); else classname = strcpy(new char[strlen(name)+1], name); } else { number = atoi(&colon[1]); classname = strcpy(new char[strlen(name)+1], name); *strrchr(classname,':') = '\0'; } const ClassDesc *cd = 0; if (classname) { cd = ClassDesc::name_to_class_desc(classname); if (!cd) { ExEnv::errn() << "ERROR: StateIn: class " << classname << " unknown" << endl; abort(); } delete[] classname; } int classid; if (cd) classid = classidmap_[(ClassDesc*)cd]; else classid = -1; std::map<int,StateInData>::iterator i; int nfound = 0; for (i=ps_.begin(); i!=ps_.end(); i++) { if (classid == -1 || i->second.type == classid) nfound++; if (nfound == number) { if (i->second.ptr.nonnull()) { p = i->second.ptr; } else { seek(i->second.offset); r += getobject(p); } return r; } } return r;}intStateIn::getobject(Ref<SavableState> &p){ int use_dir = use_directory(); int r=0; int refnum; int original_loc=0; if (use_dir) original_loc = tell(); int size_refnum; r += (size_refnum = get(refnum)); if (refnum == 0) { // reference to null#if DEBUG ExEnv::outn() << indent << "getting null object" << endl;#endif p = 0; } else {#if DEBUG ExEnv::outn() << indent << "getting object number " << setw(2) << refnum << endl; ExEnv::outn() << incindent;#endif std::map<int,StateInData>::iterator ind = ps_.find(refnum); if (ind == ps_.end() && use_dir) { ExEnv::errn() << "ERROR: StateIn: directory missing object number " << refnum << endl; abort(); } if (ind == ps_.end() || ind->second.ptr.null()) {#if DEBUG ExEnv::outn() << indent << "reading object" << endl;#endif // object has not yet been read in int need_seek = 0; if (use_dir) { if (original_loc != ind->second.offset) { need_seek = 1; original_loc = tell();#if DEBUG ExEnv::outn() << indent << "seeking to" << setw(5) << ind->second.offset << endl;#endif seek(ind->second.offset); int trefnum; get(trefnum); if (trefnum != refnum) { ExEnv::errn() << "StateIn: didn't find expected reference"<<endl; abort(); } } } const ClassDesc *cd; r += get(&cd); have_classdesc(); nextobject(refnum); DescribedClass *dc = cd->create(*this); p = dynamic_cast<SavableState*>(dc); if (use_dir) { ind->second.ptr = p; if (need_seek) seek(original_loc); }#if DEBUG ExEnv::outn() << indent << "got object with type = " << p->class_name() << endl;#endif } else { // object already exists p = ind->second.ptr;#if DEBUG ExEnv::outn() << indent << "object already existed, type = " << p->class_name() << endl; ExEnv::outn() << indent << " use_dir = " << use_dir << " tell() = " << setw(5) << tell() << " offset = " << setw(5) << ind->second.offset << " size_refnum = " << setw(1) << size_refnum << endl;#endif if (use_dir && tell() - size_refnum == ind->second.offset) { seek(tell() - size_refnum + ind->second.size);#if DEBUG ExEnv::outn() << indent << " seeking to " << tell() - size_refnum + ind->second.offset << endl;#endif } }#if DEBUG ExEnv::outn() << decindent;#endif } return r;}voidStateIn::nextobject(int objnum){ expected_object_num_ = objnum;}voidStateIn::haveobject(const Ref<SavableState> &p){ if (expected_object_num_) { haveobject(expected_object_num_,p); expected_object_num_ = 0; }}voidStateIn::haveobject(int objnum,const Ref<SavableState> &p){ std::map<int,StateInData>::iterator ind = ps_.find(objnum); if (ind == ps_.end()) { ps_[objnum].ptr = p;#if DEBUG ExEnv::outn() << indent << "have object adding number " << objnum << endl;#endif } else { ind->second.ptr = p;#if DEBUG ExEnv::outn() << indent << "have object updating number " << objnum << endl;#endif }}voidStateIn::get_header(){ const char *magic = "\001SCSO\002"; char tmp[7]; get_array_char(tmp,6); tmp[6] = '\0'; if (strcmp(tmp,magic)) { ExEnv::errn() << "StateIn: bad magic number" << endl; abort(); } get_array_char(&format_,1); // switch to the new format if (translate_->translator()->format_code() != format_) { delete translate_; translate_ = new TranslateDataIn(this,TranslateData::vctor(format_)); } get_array_int(&version_,1); get_array_char(userid_,9); get_array_int(&date_,1); // get the directory location get_array_int(&dir_loc_,1); if (dir_loc_ == -1) { ExEnv::errn() << "ERROR: StateIn: directory corrupted" << endl; abort(); }}/////////////////////////////////////////////////////////////////////////////StateClassData::~StateClassData(){ delete[] name;}StateClassData &StateClassData::operator=(const StateClassData &d){ version = d.version; classdesc = d.classdesc; ninstance = d.ninstance; if (d.name) name = strcpy(new char[strlen(d.name)+1], d.name); else name = 0; return *this;}/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ"// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -