00001
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
00034
00035 #ifndef GROOVX_IO_FIELDS_CC_UTC20051109000948_DEFINED
00036 #define GROOVX_IO_FIELDS_CC_UTC20051109000948_DEFINED
00037
00038 #include "io/fields.h"
00039
00040 #include "io/reader.h"
00041 #include "io/writer.h"
00042
00043 #include "nub/signal.h"
00044
00045 #include "rutz/error.h"
00046 #include "rutz/iter.h"
00047 #include "rutz/sfmt.h"
00048
00049 #include <map>
00050
00051 #include "rutz/trace.h"
00052 #include "rutz/debug.h"
00053 GVX_DBG_REGISTER
00054
00055 using rutz::fstring;
00056
00057 void FieldAux::throwNotAllowed(const char* what,
00058 const rutz::file_pos& pos)
00059 {
00060 throw rutz::error(rutz::sfmt("'%s' operation not allowed "
00061 "for that field", what), pos);
00062 }
00063
00064 FieldImpl::~FieldImpl() {}
00065
00067
00068
00069
00071
00072 class FieldMap::Impl
00073 {
00074 private:
00075 Impl(const Impl&);
00076 Impl& operator=(const Impl&);
00077
00078 public:
00079 typedef std::map<fstring, const Field*> MapType;
00080 MapType nameMap;
00081 const Field* const ioBegin;
00082 const Field* const ioEnd;
00083
00084 const FieldMap* parent;
00085
00086 Impl(const Field* begin, const Field* end,
00087 const FieldMap* par) :
00088 nameMap(),
00089 ioBegin(begin),
00090 ioEnd(end),
00091 parent(par)
00092 {
00093 while (begin != end)
00094 {
00095 nameMap.insert(MapType::value_type(begin->name(), begin));
00096 ++begin;
00097 }
00098 }
00099 };
00100
00101 void FieldMap::init(const Field* begin, const Field* end,
00102 const FieldMap* parent)
00103 {
00104 GVX_ASSERT(rep == 0);
00105 rep = new Impl(begin, end, parent);
00106 }
00107
00108 FieldMap::~FieldMap()
00109 {
00110 delete rep;
00111 }
00112
00113 const FieldMap* FieldMap::emptyFieldMap()
00114 {
00115 static const FieldMap* emptyMap = 0;
00116 if (emptyMap == 0)
00117 emptyMap = new FieldMap(static_cast<Field*>(0),
00118 static_cast<Field*>(0),
00119 static_cast<FieldMap*>(0));
00120 return emptyMap;
00121 }
00122
00123 bool FieldMap::hasParent() const throw()
00124 {
00125 return (rep->parent != 0);
00126 }
00127
00128 const FieldMap* FieldMap::parent() const throw()
00129 {
00130 return rep->parent;
00131 }
00132
00133 const Field& FieldMap::field(const fstring& name) const
00134 {
00135 Impl::MapType::const_iterator itr = rep->nameMap.find(name);
00136
00137 if (itr != rep->nameMap.end())
00138 return *((*itr).second);
00139
00140 if (hasParent())
00141 {
00142 return parent()->field(name);
00143 }
00144 else
00145 {
00146 throw rutz::error(rutz::sfmt("no such field: '%s'", name.c_str()),
00147 SRC_POS);
00148 }
00149 }
00150
00151 FieldMap::Iterator FieldMap::ioFields() const
00152 {
00153 return Iterator(rep->ioBegin, rep->ioEnd);
00154 }
00155
00156
00157
00159
00160
00161
00163
00164 FieldContainer::FieldContainer(nub::signal0* sig) :
00165 itsFieldMap(FieldMap::emptyFieldMap()),
00166 itsSignal(sig)
00167 {}
00168
00169 FieldContainer::~FieldContainer() throw() {}
00170
00171 void FieldContainer::setFieldMap(const FieldMap& fields)
00172 {
00173 itsFieldMap = &fields;
00174 }
00175
00176 const Field& FieldContainer::field(const rutz::fstring& name) const
00177 {
00178 return itsFieldMap->field(name);
00179 }
00180
00181 void FieldContainer::touch() const
00182 {
00183 if (itsSignal)
00184 itsSignal->emit();
00185 }
00186
00187 void FieldContainer::readFieldsFrom(io::reader& reader,
00188 const FieldMap& fields)
00189 {
00190 GVX_TRACE("FieldContainer::readFieldsFrom");
00191
00192 const io::version_id svid = reader.input_version_id();
00193
00194 for (FieldMap::Iterator itr(fields.ioFields()); itr.is_valid(); ++itr)
00195 {
00196 if (!itr->isTransient() && itr->shouldSerialize(svid))
00197 itr->readValueFrom(this, reader);
00198 }
00199
00200 if (itsSignal)
00201 itsSignal->emit();
00202 }
00203
00204 void FieldContainer::writeFieldsTo(io::writer& writer,
00205 const FieldMap& fields,
00206 io::version_id svid) const
00207 {
00208 GVX_TRACE("FieldContainer::writeFieldsTo");
00209
00210 for (FieldMap::Iterator itr(fields.ioFields()); itr.is_valid(); ++itr)
00211 {
00212 if (!itr->isTransient() && itr->shouldSerialize(svid))
00213 itr->writeValueTo(this, writer);
00214 }
00215 }
00216
00217 FieldContainer* FieldContainer::child() const
00218 {
00219 GVX_TRACE("FieldContainer::child");
00220 return 0;
00221 }
00222
00223 static const char __attribute__((used)) vcid_groovx_io_fields_cc_utc20051109000948[] = "$Id: fields.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00224 #endif // !GROOVX_IO_FIELDS_CC_UTC20051109000948DEFINED