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 #include "bufferedproperty.hh"
00026
00027 set<BufferedLocalProperty*> BufferedLocalProperty::allblps;
00028 set<BufferedRemoteProperty*> BufferedRemoteProperty::allbrps;
00029
00030
00031
00032 BufferedLocalProperty::BufferedLocalProperty(MetaObject* superobject)
00033 : MetaObject(superobject), Property(superobject), LocalProperty(superobject), changed(false)
00034 {
00035 allblps.insert(this);
00036 }
00037
00038 BufferedLocalProperty::BufferedLocalProperty(MetaObject* superobject, const string& d, const string& dt)
00039 : MetaObject(superobject), Property(superobject), LocalProperty(superobject, d, dt), changed(false)
00040 {
00041 allblps.insert(this);
00042 }
00043
00044 BufferedLocalProperty::~BufferedLocalProperty()
00045 {
00046 allblps.erase(this);
00047 }
00048
00049 MetaObject* BufferedLocalProperty::new_BufferedLocalProperty(MetaObject* superobject, const string& type)
00050 {
00051 return new BufferedLocalProperty(superobject);
00052 }
00053
00054 void BufferedLocalProperty::write(int start, const string& newdata)
00055 {
00056 string oldvalue;
00057 read(oldvalue);
00058
00059 Property::write(start, newdata);
00060
00061 vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyWrite,
00062 *this, *this,
00063 start, newdata.size(),
00064 read(), getDataType(),
00065 oldvalue, getDataType(),
00066 false);
00067
00068 for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00069 if(! dynamic_cast<PropertyListenerSiteWrapper*>((*i).second))
00070 (*i).second->notifyPropertyChange(*event);
00071 }
00072 changed = true;
00073 changestart = start;
00074 changelen = newdata.length();
00075 }
00076
00077 void BufferedLocalProperty::replace(const string& newdata, const string& newtype)
00078 {
00079 string oldvalue;
00080 read(oldvalue);
00081
00082 Property::replace(newdata, newtype);
00083 string r;
00084 read(r);
00085
00086 vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyReplace,
00087 *this, *this,
00088 read(), getDataType(),
00089 oldvalue, getDataType(),
00090 false);
00091
00092
00093 for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00094 if(! dynamic_cast<PropertyListenerSiteWrapper*>((*i).second))
00095 (*i).second->notifyPropertyChange(*event);
00096 }
00097 changed = true;
00098 changestart = 0;
00099 changelen = getLength();
00100 }
00101
00102 void BufferedLocalProperty::flush()
00103 {
00104 if(changed) {
00105
00106 vRef<PropertyEvent> event;
00107 if(changestart == 0 && changelen == getLength()) {
00108 event = new PropertyEvent(PropertyEvent::PropertyReplace,
00109 *this, *this,
00110 read(), getDataType(),
00111 false);
00112 } else {
00113 event =
00114 new PropertyEvent(PropertyEvent::PropertyWrite,
00115 *this, *this,
00116 changestart, changelen,
00117 read(), getDataType(),
00118 false);
00119
00120 }
00121
00122 for(PropertyListenerMap::iterator n = propertyListeners.begin();
00123 n != propertyListeners.end(); n++) {
00124 string s;
00125 readRaw(s, changestart, changelen);
00126 if(dynamic_cast<PropertyListenerSiteWrapper*>((*n).second)) {
00127 (*n).second->notifyPropertyChange(*event);
00128 }
00129 }
00130 changed = false;
00131 }
00132 }
00133
00134 void BufferedLocalProperty::flushAll()
00135 {
00136 for(set<BufferedLocalProperty*>::iterator i = allblps.begin(); i != allblps.end(); i++) {
00137 try {
00138 (*i)->flush();
00139 } catch(runtime_error e) {
00140 LOG("bufferedproperty", 2, "flushAll caught exception: " << e.what());
00141 }
00142 }
00143 }
00144
00145 void BufferedLocalProperty::registerExtenders()
00146 {
00147 static bool done = false;
00148 if(! done) {
00149 LocalSite::addLocalObjectExtension(typeid(BufferedLocalProperty).name(),
00150 &BufferedLocalProperty::new_BufferedLocalProperty);
00151 LocalSite::addLocalObjectExtension(typeid(LocalProperty).name(),
00152 &BufferedLocalProperty::new_BufferedLocalProperty);
00153 LocalSite::addLocalObjectExtension(typeid(Property).name(),
00154 &BufferedLocalProperty::new_BufferedLocalProperty);
00155 LocalSite::addLocalObjectExtension("property:property",
00156 &BufferedLocalProperty::new_BufferedLocalProperty);
00157 done = true;
00158 }
00159 }
00160
00161
00162
00163 BufferedRemoteProperty::BufferedRemoteProperty(MetaObject* superobject)
00164 : MetaObject(superobject), Property(superobject), RemoteProperty(superobject), changed(false), lastmsgsuccess(false)
00165 {
00166 allbrps.insert(this);
00167 }
00168
00169 MetaObject* BufferedRemoteProperty::new_BufferedRemoteProperty(MetaObject* superobject, const string& type)
00170 {
00171 return new BufferedRemoteProperty(superobject);
00172 }
00173
00174 BufferedRemoteProperty::~BufferedRemoteProperty()
00175 {
00176 allbrps.erase(this);
00177 }
00178
00179 void BufferedRemoteProperty::write(int start, const string& newdata)
00180 {
00181 string oldvalue;
00182 Property::read(oldvalue);
00183
00184 Property::write(start, newdata);
00185 changed = true;
00186 changestart = start;
00187 changelen = newdata.length();
00188
00189 if(lastmsgsuccess) {
00190 vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyWrite,
00191 *this, *this,
00192 start, newdata.size(),
00193 Property::read(), getDataType(),
00194 oldvalue, getDataType(),
00195 false);
00196
00197
00198 for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00199 (*i).second->notifyPropertyChange(*event);
00200 }
00201 }
00202 }
00203
00204 void BufferedRemoteProperty::replace(const string& newdata, const string& newtype)
00205 {
00206 string olddatatype = Property::getDataType();
00207 string oldvalue;
00208 Property::read(oldvalue);
00209
00210 Property::replace(newdata, newtype);
00211 changed = true;
00212 changestart = 0;
00213 changelen = getLength();
00214
00215 if(lastmsgsuccess) {
00216 vRef<PropertyEvent> event = new PropertyEvent(PropertyEvent::PropertyReplace,
00217 *this, *this,
00218 newdata, newtype,
00219 oldvalue, olddatatype,
00220 false);
00221
00222 for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00223 (*i).second->notifyPropertyChange(*event);
00224 }
00225 }
00226 }
00227
00228 void BufferedRemoteProperty::flush()
00229 {
00230 if(changed) {
00231 LOG("BufferedRemoteProperty", 3, "flushing " << getURL().getString());
00232 if(changestart == 0 && changelen == getRawLength()) {
00233 pREF(Message*, m, new Message(),
00234 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:replace", true),
00235 lastnonce = m->getNonce();
00236 string s;
00237 readRaw(s, 0, getRawLength());
00238 m->insertField(-1, "data", s);
00239
00240 m->insertField(-1, "datatype", getRawDataType());
00241 sendMessage(m);
00242 );
00243 );
00244 } else {
00245 pREF(Message*, m, new Message(),
00246 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:write", true),
00247 lastnonce = m->getNonce();
00248 char x[16];
00249 sprintf(x, "%i", changestart);
00250 string s;
00251 readRaw(s, changestart, changelen);
00252 m->insertField(-1, "start", x);
00253 m->insertField(-1, "data", s);
00254 sendMessage(m);
00255 );
00256 );
00257 }
00258 changed = false;
00259 }
00260 }
00261
00262 void BufferedRemoteProperty::flushAll()
00263 {
00264 for(set<BufferedRemoteProperty*>::iterator i = allbrps.begin(); i != allbrps.end(); i++) {
00265 (*i)->flush();
00266 }
00267 }
00268
00269 void BufferedRemoteProperty::sendUpdateMessage(Message* m)
00270 {
00271 if(!(changed && lastmsgsuccess)) RemoteProperty::sendUpdateMessage(m);
00272
00273 if(m->getNonce() == lastnonce
00274 && (m->getMethod() == "property:update"
00275 || m->getMethod() == "property:replace-update"))
00276 {
00277 try {
00278 m->getField("data");
00279 lastmsgsuccess = true;
00280 } catch(Message::NoSuchFieldError) {
00281 try {
00282 m->getField("error");
00283 lastmsgsuccess = false;
00284 } catch(Message::NoSuchFieldError) { }
00285 }
00286 }
00287 }
00288
00289 void BufferedRemoteProperty::registerExtenders()
00290 {
00291 static bool done = false;
00292 if(! done) {
00293 RemoteSite::addRemoteObjectExtension(typeid(BufferedRemoteProperty).name(),
00294 &BufferedRemoteProperty::new_BufferedRemoteProperty);
00295 RemoteSite::addRemoteObjectExtension(typeid(RemoteProperty).name(),
00296 &BufferedRemoteProperty::new_BufferedRemoteProperty);
00297 RemoteSite::addRemoteObjectExtension(typeid(Property).name(),
00298 &BufferedRemoteProperty::new_BufferedRemoteProperty);
00299 RemoteSite::addRemoteObjectExtension("property:property",
00300 &BufferedRemoteProperty::new_BufferedRemoteProperty);
00301 done = true;
00302 }
00303 }