/** * \file internal/particle_save.h * \brief Various useful utilities * * Copyright 2007-2010 IMP Inventors. All rights reserved. */ #ifndef IMP_INTERNAL_PARTICLE_SAVE_H #define IMP_INTERNAL_PARTICLE_SAVE_H #include "../Particle.h" #include "map.h" #include #include IMP_BEGIN_INTERNAL_NAMESPACE // skips empty lines class LineStream{ std::istream &in_; std::vector indents_; std::vector lines_; bool has_indent(std::string str, unsigned int indent) { for (unsigned int i=0; i< indent; ++i) { if (i== str.size()) return false; if (str[i] != ' ') return false; } if (str[indent] ==' ') { IMP_THROW("Excessive indent (not " << indent << ") on line " << str, IOException); } return true; } bool not_white(char buf[]) const { for (int i=0; buf[i] != '\0'; ++i) { if (buf[i] != ' ') return true; } return false; } int get_indent(std::string str) { for (unsigned int i=0; i< str.size(); ++i) { if (str[i] != ' ') return i; } return -1; } void fill_buffer() { while (lines_.empty()) { char buf[3000]; in_.getline(buf, 3000); if (!in_) return; if (buf[0] == '#') continue; if (not_white(buf)) { IMP_LOG(VERBOSE, "Found line " << buf << std::endl); lines_.push_back(buf); } } } public: typedef std::pair LinePair; LineStream(std::istream &init): in_(init), indents_(1,0){} void pop_indent() { IMP_INTERNAL_CHECK(indents_.size() >=1, "Too many pops"); indents_.pop_back(); if (!indents_.empty()) { IMP_LOG(VERBOSE, "Indent is now " << indents_.back() << std::endl); } } void push_indent() { fill_buffer(); if (!lines_.empty()) { int id=(get_indent(lines_.back())); if (id == indents_.back()) ++id; indents_.push_back(std::max(id, indents_.back()+1)); } } LinePair get_line() { fill_buffer(); if (lines_.empty()) { IMP_LOG(VERBOSE, "Hit end of line buffer"< pos+2) { value= std::string(ret, pos+2); } return std::make_pair(key, value); } }; class IMPEXPORT ParticleData { friend class ParticleDiff; typedef ArrayStorage FloatTable; typedef ArrayStorage OptimizedTable; typedef ArrayStorage IntTable; typedef ArrayStorage StringTable; typedef RefCountedStorage ParticleTable; typedef RefCountedStorage ObjectTable; std::string name_; FloatTable floats_; OptimizedTable optimizeds_; IntTable ints_; StringTable strings_; ParticleTable particles_; ObjectTable objects_; public: ParticleData(){} //! Store the data from the particle ParticleData(Particle *p); //! Store the data from the particle ParticleData(Particle *p, const FloatKeys &keys); //! overwrite the particle void apply(Particle *p) const; void apply(Particle *p, const FloatKeys &keys) const; void show(std::ostream &out=std::cout) const; void write_yaml(std::ostream &out, const internal::Map &particles) const; void read_yaml(LineStream &in, const internal::Map &particles); }; IMP_OUTPUT_OPERATOR(ParticleData); class IMPEXPORT ParticleDiff { typedef std::pair FloatPair; typedef std::pair IntPair; typedef std::pair StringPair; typedef std::pair > ParticlePair; typedef std::pair > ObjectPair; std::vector floats_a_; std::vector floats_r_; std::vector optimizeds_a_, optimizeds_r_; std::vector ints_a_; std::vector ints_r_; std::vector strings_a_; std::vector strings_r_; std::vector particles_a_; std::vector particles_r_; std::vector objects_a_; std::vector objects_r_; public: ParticleDiff(){} //! Compute the diff between the two ParticleDiff(const ParticleData &base, Particle *p); void apply(Particle *p) const; void show(std::ostream &out=std::cout) const; }; IMP_OUTPUT_OPERATOR(ParticleDiff); IMP_END_INTERNAL_NAMESPACE #endif /* IMP_INTERNAL_PARTICLE_SAVE_H */