00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "stdafx.h"
00011 #include "cphidgetdictionary.h"
00012 #include "csocket.h"
00013 #include "csocketevents.h"
00014 #include "cphidgetlist.h"
00015 #include "cphidgetmanager.h"
00016
00017 int CPhidgetDictionary_areEqual(void *arg1, void *arg2)
00018 {
00019 if(arg1 == arg2) return 1;
00020 return 0;
00021 }
00022
00023 void CPhidgetDictionary_free(void *arg)
00024 {
00025 CPhidgetDictionaryHandle dict = arg;
00026
00027 if(!dict)
00028 return;
00029
00030 CThread_mutex_lock(&dict->listenersLock);
00031 CList_emptyList((CListHandle *)&dict->listeners, PTRUE, CPhidgetDictionaryListener_free);
00032 CThread_mutex_unlock(&dict->listenersLock);
00033
00034 CThread_mutex_destroy(&dict->lock);
00035 CThread_mutex_destroy(&dict->listenersLock);
00036 CThread_mutex_destroy(&dict->openCloseLock);
00037
00038 free(dict); dict = NULL;
00039 }
00040
00041 int CPhidgetDictionaryListener_areEqual(void *arg1, void *arg2)
00042 {
00043 if(arg1 == arg2) return 1;
00044 return 0;
00045 }
00046
00047 void CPhidgetDictionaryListener_free(void *arg)
00048 {
00049 CPhidgetDictionaryListenerHandle dict = arg;
00050
00051 if(!dict)
00052 return;
00053 free(dict); dict = NULL;
00054 }
00055
00056 int CCONV CPhidgetDictionary_create(CPhidgetDictionaryHandle *dict)
00057 {
00058 CPhidgetDictionaryHandle dicttemp = 0;
00059
00060 TESTPTR(dict)
00061
00062 if(!(dicttemp = (CPhidgetDictionaryHandle)malloc(sizeof(CPhidgetDictionary))))
00063 return EPHIDGET_NOMEMORY;
00064 ZEROMEM(dicttemp, sizeof(CPhidgetDictionary));
00065
00066 CThread_mutex_init(&dicttemp->lock);
00067 CThread_mutex_init(&dicttemp->listenersLock);
00068 CThread_mutex_init(&dicttemp->openCloseLock);
00069
00070 *dict = dicttemp;
00071 return EPHIDGET_OK;
00072 }
00073
00074 int CCONV CPhidgetDictionary_close(CPhidgetDictionaryHandle dict)
00075 {
00076 int result = EPHIDGET_OK;
00077 TESTPTR(dict)
00078
00079 CThread_mutex_lock(&dict->openCloseLock);
00080 if (!CPhidget_statusFlagIsSet(dict->status, PHIDGET_OPENED_FLAG))
00081 {
00082 LOG(PHIDGET_LOG_WARNING, "Close was called on an already closed Dictionary handle.");
00083 CThread_mutex_unlock(&dict->openCloseLock);
00084 return EPHIDGET_OK;
00085 }
00086
00087 if((result = unregisterRemoteDictionary(dict)) != EPHIDGET_OK)
00088 {
00089 CThread_mutex_unlock(&dict->openCloseLock);
00090 return result;
00091 }
00092
00093 CPhidget_clearStatusFlag(&dict->status, PHIDGET_OPENED_FLAG, &dict->lock);
00094 CThread_mutex_unlock(&dict->openCloseLock);
00095 return EPHIDGET_OK;
00096 }
00097
00098 int CCONV CPhidgetDictionary_delete(CPhidgetDictionaryHandle dict)
00099 {
00100 CPhidgetDictionary_free(dict);
00101 return EPHIDGET_OK;
00102 }
00103
00104 int CCONV CPhidgetDictionary_getServerID(CPhidgetDictionaryHandle dict, const char **serverID)
00105 {
00106 return CPhidget_getServerID((CPhidgetHandle)dict, serverID);
00107 }
00108 int CCONV CPhidgetDictionary_getServerAddress(CPhidgetDictionaryHandle dict, const char **address, int *port)
00109 {
00110 return CPhidget_getServerAddress((CPhidgetHandle)dict, address, port);
00111 }
00112 int CCONV CPhidgetDictionary_getServerStatus(CPhidgetDictionaryHandle dict, int *status)
00113 {
00114 return CPhidget_getServerStatus((CPhidgetHandle)dict, status);
00115 }
00116
00117 int CCONV CPhidgetDictionary_set_OnError_Handler(CPhidgetDictionaryHandle dict,
00118 int(CCONV *fptr)(CPhidgetDictionaryHandle, void *, int, const char *), void *userPtr)
00119 {
00120 TESTPTR(dict)
00121 dict->fptrError = fptr;
00122 dict->fptrErrorptr = userPtr;
00123 return EPHIDGET_OK;
00124 }
00125
00126
00127 int CCONV CPhidgetDictionary_addKey(CPhidgetDictionaryHandle dict, const char *key, const char *val, int persistent)
00128 {
00129 TESTPTR(dict)
00130 TESTPTRS(key, val)
00131
00132 CThread_mutex_lock(&dict->lock);
00133 if(!CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG))
00134 {
00135 CThread_mutex_unlock(&dict->lock);
00136 return EPHIDGET_NETWORK_NOTCONNECTED;
00137 }
00138
00139 pdc_async_set(dict->networkInfo->server->pdcs, key, val, (int)strlen(val), persistent?0:1, internal_async_network_error_handler, dict);
00140
00141 CThread_mutex_unlock(&dict->lock);
00142
00143 return EPHIDGET_OK;
00144 }
00145
00146 int CCONV CPhidgetDictionary_removeKey(CPhidgetDictionaryHandle dict, const char *pattern)
00147 {
00148
00149
00150 TESTPTRS(dict, pattern)
00151
00152 CThread_mutex_lock(&dict->lock);
00153 if(!CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG))
00154 {
00155 CThread_mutex_unlock(&dict->lock);
00156 return EPHIDGET_NETWORK_NOTCONNECTED;
00157 }
00158
00159
00160
00161
00162
00163 pdc_async_remove(dict->networkInfo->server->pdcs, pattern, internal_async_network_error_handler, dict);
00164
00165 CThread_mutex_unlock(&dict->lock);
00166
00167
00168 return EPHIDGET_OK;
00169 }
00170
00171 int CCONV CPhidgetDictionary_getKey(CPhidgetDictionaryHandle dict, const char *key, char *val, int vallen)
00172 {
00173 int ret;
00174
00175 TESTPTRS(dict, key)
00176 TESTPTR(val)
00177
00178 CThread_mutex_lock(&dict->lock);
00179 if(!CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG))
00180 {
00181 ret = EPHIDGET_NETWORK_NOTCONNECTED;
00182 }
00183 else
00184 {
00185 int result, size;
00186 char err[1024], *keywrap;
00187
00188
00189
00190 size = (int)strlen(key);
00191 keywrap = (char *)malloc(size+3);
00192 snprintf(keywrap, size+3, "^%s$",key);
00193
00194 CThread_mutex_lock(&dict->networkInfo->server->pdc_lock);
00195 if(!dict->networkInfo->server->pdcs)
00196 ret = EPHIDGET_NETWORK_NOTCONNECTED;
00197 else
00198 {
00199 result = pdc_get(dict->networkInfo->server->pdcs, keywrap, val, vallen, err, sizeof(err));
00200 switch(result)
00201 {
00202 case 1:
00203 ret = EPHIDGET_OK;
00204 break;
00205 case 2:
00206 ret = EPHIDGET_NOTFOUND;
00207 break;
00208 case 0:
00209 default:
00210 ret = EPHIDGET_UNEXPECTED;
00211 break;
00212 }
00213 }
00214 CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock);
00215
00216 free(keywrap);
00217 }
00218
00219 CThread_mutex_unlock(&dict->lock);
00220
00221 return ret;
00222 }
00223
00224 void dict_event_handler(const char *key, const char *val, unsigned int len, pdict_reason_t reason, void *ptr)
00225 {
00226 CPhidgetDictionaryListenerHandle listener = ptr;
00227
00228 if(!listener) return;
00229
00230 if(listener->fptr)
00231 listener->fptr(listener->dict, listener->userPtr, key, val, (CPhidgetDictionary_keyChangeReason)reason);
00232 return;
00233 }
00234
00235 int CCONV CPhidgetDictionary_set_OnServerConnect_Handler(CPhidgetDictionaryHandle dict, int (CCONV *fptr)(CPhidgetDictionaryHandle dict, void *userPtr), void *userPtr)
00236 {
00237 TESTPTR(dict)
00238 dict->fptrServerConnect = fptr;
00239 dict->fptrServerConnectptr = userPtr;
00240 return EPHIDGET_OK;
00241 }
00242 int CCONV CPhidgetDictionary_set_OnServerDisconnect_Handler(CPhidgetDictionaryHandle dict, int (CCONV *fptr)(CPhidgetDictionaryHandle dict, void *userPtr), void *userPtr)
00243 {
00244 TESTPTR(dict)
00245 dict->fptrServerDisconnect = fptr;
00246 dict->fptrServerDisconnectptr = userPtr;
00247 return EPHIDGET_OK;
00248 }
00249
00250 int CCONV CPhidgetDictionary_set_OnKeyChange_Handler(CPhidgetDictionaryHandle dict, CPhidgetDictionaryListenerHandle *dictlistener, const char *pattern,
00251 int(CCONV *fptr)(CPhidgetDictionaryHandle dict, void *userPtr, const char *key, const char *val, CPhidgetDictionary_keyChangeReason reason),
00252 void *userPtr)
00253 {
00254 CPhidgetDictionaryListenerHandle dict_listener;
00255 char errdesc[1024];
00256 int result;
00257
00258 TESTPTRS(dict, pattern)
00259 TESTPTR(dictlistener)
00260
00261 CThread_mutex_lock(&dict->lock);
00262 if(!CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG))
00263 {
00264 CThread_mutex_unlock(&dict->lock);
00265 return EPHIDGET_NETWORK_NOTCONNECTED;
00266 }
00267
00268 if(!(dict_listener = malloc(sizeof(CPhidgetDictionaryListener))))
00269 {
00270 CThread_mutex_unlock(&dict->lock);
00271 return EPHIDGET_NOMEMORY;
00272 }
00273 ZEROMEM(dict_listener, sizeof(CPhidgetDictionaryListener));
00274
00275 dict_listener->dict = dict;
00276 dict_listener->fptr = fptr;
00277 dict_listener->userPtr = userPtr;
00278
00279 CThread_mutex_lock(&dict->networkInfo->server->pdc_lock);
00280 if (!(dict_listener->listen_id = pdc_listen(dict->networkInfo->server->pdcs, pattern, dict_event_handler, dict_listener, errdesc, sizeof (errdesc))))
00281 {
00282 LOG(PHIDGET_LOG_DEBUG,"pdc_listen: %s", errdesc);
00283 free(dict_listener);
00284 CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock);
00285 CThread_mutex_unlock(&dict->lock);
00286 return EPHIDGET_UNEXPECTED;
00287 }
00288 CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock);
00289
00290 CThread_mutex_lock(&dict->listenersLock);
00291 if((result = CList_addToList((CListHandle *)&dict->listeners, dict_listener, CPhidgetDictionaryListener_areEqual)))
00292 {
00293 CThread_mutex_unlock(&dict->listenersLock);
00294 CThread_mutex_lock(&dict->networkInfo->server->pdc_lock);
00295 pdc_ignore(dict->networkInfo->server->pdcs, dict_listener->listen_id, NULL, 0);
00296 CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock);
00297 free(dict_listener);
00298 CThread_mutex_unlock(&dict->lock);
00299 return result;
00300 }
00301 CThread_mutex_unlock(&dict->listenersLock);
00302 CThread_mutex_unlock(&dict->lock);
00303
00304 *dictlistener = dict_listener;
00305
00306 return EPHIDGET_OK;
00307 }
00308
00309
00310 int CCONV CPhidgetDictionary_remove_OnKeyChange_Handler(CPhidgetDictionaryListenerHandle keylistener)
00311 {
00312 int result = 0;
00313 char errdesc[1024];
00314 CPhidgetDictionaryHandle dict;
00315
00316 TESTPTR(keylistener)
00317 dict = keylistener->dict;
00318
00319 CThread_mutex_lock(&dict->lock);
00320
00321 if(CPhidget_statusFlagIsSet(dict->status, PHIDGET_SERVER_CONNECTED_FLAG))
00322 {
00323 CThread_mutex_lock(&dict->networkInfo->server->pdc_lock);
00324 if(!(result = pdc_ignore(dict->networkInfo->server->pdcs, keylistener->listen_id, errdesc, sizeof (errdesc))))
00325 {
00326 LOG(PHIDGET_LOG_WARNING,"pdc_ignore: %s",errdesc);
00327 CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock);
00328 CThread_mutex_unlock(&dict->lock);
00329 return EPHIDGET_UNEXPECTED;
00330 }
00331 CThread_mutex_unlock(&dict->networkInfo->server->pdc_lock);
00332 }
00333
00334 CThread_mutex_lock(&dict->listenersLock);
00335 if((result = CList_removeFromList((CListHandle *)&dict->listeners, keylistener,
00336 CPhidgetDictionaryListener_areEqual, PTRUE, CPhidgetDictionaryListener_free)))
00337 {
00338 CThread_mutex_unlock(&dict->listenersLock);
00339 CThread_mutex_unlock(&dict->lock);
00340 return result;
00341 }
00342 CThread_mutex_unlock(&dict->listenersLock);
00343 CThread_mutex_unlock(&dict->lock);
00344
00345 return EPHIDGET_OK;
00346 }