00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <iostream>
00025 #include <fstream>
00026
00027 #include <vos/corelibs/vos/vos.hh>
00028 #include "property.hh"
00029 #include <typechain/typechain.hh>
00030
00031 #include <assert.h>
00032
00033 RemoteProperty::RemoteProperty(MetaObject* superobject)
00034 : MetaObject(superobject), Property(superobject), offset(-1), first_read(true)
00035 {
00036 addUpdateHandler<RemoteProperty>("property:length-update", this, &RemoteProperty::lengthUpdateHandler);
00037 addUpdateHandler<RemoteProperty>("property:update", this, &RemoteProperty::writeUpdateHandler);
00038 addUpdateHandler<RemoteProperty>("property:replace-update", this, &RemoteProperty::replaceUpdateHandler);
00039 addUpdateHandler<RemoteProperty>("property:start-listening-reply", this, &RemoteProperty::startListeningReplyHandler);
00040 }
00041
00042
00043
00044
00045
00046 void RemoteProperty::checkDecoded() {
00047 if(first_read) {
00048 string foo;
00049 readRaw(foo, 0, -1);
00050 first_read = false;
00051 }
00052 Property::checkDecoded();
00053 }
00054
00055 int RemoteProperty::getRawLength()
00056 {
00057 if(propertyListeners.empty()) {
00058 pREF(Message*, m, new Message(),
00059 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:get-length", true),
00060 sendMessage(m);
00061 rREF(RemoteSite&, site, dynamic_cast<RemoteSite&>(getSite()),
00062 pREF(Message*, n, ls.waitFor(m->getNonce(), &site), );
00063 );
00064 );
00065 );
00066 }
00067
00068 return Property::getRawLength();
00069 }
00070
00071 int RemoteProperty::getLength()
00072 {
00073 string foo;
00074 readRaw(foo, 0, -1);
00075 return Property::getLength();
00076 }
00077
00078 const string RemoteProperty::getRawDataType() {
00079 if(raw_datatype == "?") {
00080 string foo;
00081 readRaw(foo, 0, -1);
00082 }
00083 return Property::getRawDataType();
00084 }
00085
00086
00087
00088 void RemoteProperty::read(string& target, int start, int length)
00089 {
00090 string foo;
00091 readRaw(foo, start, length);
00092 Property::read(target, start, length);
00093 }
00094
00095 void RemoteProperty::readRaw(string& target, int start, int length)
00096 {
00097 if(propertyListeners.empty()) {
00098 LOG("RemoteProperty", 5, "readRaw: sending read message (no listeners).");
00099 pREF(Message*, m, new Message(),
00100 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:read", true),
00101 char x[16];
00102 sprintf(x, "%i", start);
00103 m->insertField(-1, "start", x);
00104 sprintf(x, "%i", length);
00105 m->insertField(-1, "length", x);
00106
00107 sendMessage(m);
00108 rREF(RemoteSite&, site, dynamic_cast<RemoteSite&>(getSite()),
00109 pREF(Message*, n, ls.waitFor(m->getNonce(), &site), );
00110 );
00111 );
00112 );
00113 }
00114
00115 Property::readRaw(target, start, length);
00116 }
00117
00118 void RemoteProperty::asyncRead()
00119 {
00120 if(propertyListeners.empty()) {
00121 LOG("RemoteProperty", 5, "readRaw: sending read message (no listeners).");
00122 pREF(Message*, m, new Message(),
00123 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:read", true),
00124 m->insertField(-1, "start", "0");
00125 m->insertField(-1, "length", "-1");
00126
00127 sendMessage(m);
00128 );
00129 );
00130 } else {
00131 vRef<PropertyEvent> event = new PropertyEvent(
00132 PropertyEvent::PropertyReplace,
00133 *this, *this,
00134 data,
00135 getRawDataType(),
00136 false);
00137
00138 for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00139 (*i).second->notifyPropertyChange(*event);
00140 }
00141 }
00142 }
00143
00144 void RemoteProperty::asyncRead(int start, int length)
00145 {
00146 if(propertyListeners.empty()) {
00147 LOG("RemoteProperty", 5, "readRaw: sending read message (no listeners).");
00148 pREF(Message*, m, new Message(),
00149 rREF(LocalSite&, ls, RemoteVobject::initFields(this, m, "property:read", true),
00150 char x[16];
00151 snprintf(x, sizeof(x), "%i", start);
00152 m->insertField(-1, "start", x);
00153 snprintf(x, sizeof(x), "%i", length);
00154 m->insertField(-1, "length", x);
00155
00156 sendMessage(m);
00157 );
00158 );
00159 } else {
00160 vRef<PropertyEvent> event = new PropertyEvent(
00161 PropertyEvent::PropertyWrite,
00162 *this, *this,
00163 start, data.size(),
00164 data,
00165 getRawDataType(),
00166 false);
00167
00168 for(PropertyListenerMap::iterator i = propertyListeners.begin(); i != propertyListeners.end(); i++) {
00169 (*i).second->notifyPropertyChange(*event);
00170 }
00171 }
00172 }
00173
00174
00175 void RemoteProperty::write(int start, const string& newdata)
00176 {
00177 vRef<Message> m = new Message();
00178 vRef<LocalSite> ls = RemoteVobject::initFields(this, &m, "property:write", true);
00179 char x[16];
00180 snprintf(x, sizeof(x), "%i", start);
00181 m->insertField(-1, "start", x);
00182 m->insertField(-1, "data", newdata);
00183 sendMessage(&m);
00184 vRef<RemoteSite> site = dynamic_cast<RemoteSite&>(getSite());
00185 vRef<Message> n = ls->waitFor(m->getNonce(), &site);
00186 }
00187
00188 void RemoteProperty::replace(const string& newdata, const string& newtype)
00189 {
00190 vRef<Message> m = new Message();
00191 vRef<LocalSite> ls = RemoteVobject::initFields(this, &m, "property:replace", true);
00192 m->insertField(-1, "data", newdata);
00193
00194
00195 if(newtype == "?")
00196 m->insertField(-1, "datatype", getRawDataType());
00197 else
00198 m->insertField(-1, "datatype", newtype);
00199
00200 sendMessage(&m);
00201 vRef<RemoteSite> site = dynamic_cast<RemoteSite&>(getSite());
00202 vRef<Message> n = ls->waitFor(m->getNonce(), &site);
00203 }
00204
00205
00206
00207 void RemoteProperty::lengthUpdateHandler(Message* m)
00208 {
00209 if(m->getNumFields() > 0) {
00210 raw_length = atoi(m->getField(0).value.c_str());
00211 decoded = false;
00212 }
00213 }
00214
00215 void RemoteProperty::writeUpdateHandler(Message* m)
00216 {
00217 try {
00218 int off = atoi(m->getField("start").value.c_str());
00219 string oldvalue = raw_data;
00220 raw_data.replace(off, m->getField("data").value.size(), m->getField("data").value);
00221 raw_datatype = m->getField("datatype").value;
00222 raw_length = raw_data.size();
00223 decoded = false;
00224
00225 vRef<PropertyEvent> event =
00226 new PropertyEvent(PropertyEvent::PropertyWrite,
00227 *this, *this,
00228 off, raw_length,
00229 raw_data, raw_datatype,
00230 oldvalue, raw_datatype,
00231 false);
00232
00233 for(PropertyListenerMap::iterator i = propertyListeners.begin();
00234 i != propertyListeners.end();
00235 i++) {
00236 (*i).second->notifyPropertyChange(*event);
00237 }
00238 } catch(Message::NoSuchFieldError) {
00239 }
00240 }
00241
00242 void RemoteProperty::replaceUpdateHandler(Message* m)
00243 {
00244 try {
00245 string oldvalue = raw_data;
00246 string olddatatype = raw_datatype;
00247 raw_data = m->getField("data").value;
00248 raw_datatype = m->getField("datatype").value;
00249 raw_length = raw_data.size();
00250 decoded = false;
00251
00252 vRef<PropertyEvent> event =
00253 new PropertyEvent(PropertyEvent::PropertyReplace,
00254 *this, *this,
00255 raw_data, raw_datatype,
00256 oldvalue, olddatatype,
00257 false);
00258
00259 for(PropertyListenerMap::iterator i = propertyListeners.begin();
00260 i != propertyListeners.end();
00261 i++) {
00262 (*i).second->notifyPropertyChange(*event);
00263 }
00264 } catch(Message::NoSuchFieldError) {
00265 }
00266 }
00267
00268 void RemoteProperty::startListeningReplyHandler(Message* m)
00269 {
00270 const Message::Field& f = m->getField("listen");
00271 if(f.value == "property") {
00272 Property::addPropertyListener(&DoNothingPropertyListener::static_);
00273 }
00274 }
00275
00276 MetaObject* RemoteProperty::new_RemoteProperty(MetaObject* superobject, const string& type)
00277 {
00278 return new RemoteProperty(superobject);
00279 }
00280
00281 void RemoteProperty::addPropertyListener(PropertyListener* pl, bool refresh)
00282 {
00283 if(propertyListeners.empty()) {
00284
00285
00286 if(refresh) {
00287 vRef<Message> m = new Message();
00288 vRef<LocalSite> ls = RemoteVobject::initFields(this, &m, "property:start-listening", true);
00289 m->insertField(-1, "listen", "property");
00290
00291 sendMessage(&m);
00292
00293 vRef<Site> site = getSite();
00294 vRef<Message> r = ls->waitFor(m->getNonce(), dynamic_cast<RemoteSite*>(&site));
00295 }
00296 Property::addPropertyListener(pl, refresh);
00297 string d;
00298 readRaw(d, 0, getRawLength());
00299
00300 vRef<PropertyEvent> event =
00301 new PropertyEvent(PropertyEvent::PropertyReplace,
00302 *this, *this,
00303 d, getRawDataType(),
00304 false);
00305
00306 pl->notifyPropertyChange(*event);
00307 } else {
00308 Property::addPropertyListener(pl, refresh);
00309 string d;
00310 readRaw(d, 0, getRawLength());
00311
00312 if(refresh) {
00313 vRef<PropertyEvent> event =
00314 new PropertyEvent(PropertyEvent::PropertyReplace,
00315 *this, *this,
00316 d, getRawDataType(),
00317 false);
00318 pl->notifyPropertyChange(*event);
00319 }
00320 }
00321 }
00322
00323 void RemoteProperty::removePropertyListener(PropertyListener* pl)
00324 {
00325 Property::removePropertyListener(pl);
00326
00327 if(propertyListeners.size() == 1 && propertyListeners.count(&DoNothingPropertyListener::static_) == 1)
00328 propertyListeners.erase(&DoNothingPropertyListener::static_);
00329
00330 if(propertyListeners.empty()) {
00331 vRef<Message> m = new Message();
00332 vRef<LocalSite> ls = RemoteVobject::initFields(this, &m, "property:stop-listening", false);
00333
00334 m->insertField(-1, "listen", "property");
00335
00336 sendMessage(&m);
00337 }
00338 }
00339
00340 void RemoteProperty::clearCache()
00341 {
00342 data="";
00343 raw_data = "";
00344 datatype="?";
00345 raw_datatype = "?";
00346 offset=-1;
00347 raw_length=-1;
00348 data_length = 0;
00349 decoded = false;
00350 }